Python 检查一个类实例(在本例中用作dict键)是否与同一类的另一个实例具有所有相同的属性

Python 检查一个类实例(在本例中用作dict键)是否与同一类的另一个实例具有所有相同的属性,python,dictionary,attributes,key,instance,Python,Dictionary,Attributes,Key,Instance,我想创建一个自定义类,并使用该类的实例作为dict的键 然后我想创建该类的其他实例,并检查所有属性是否与作为该dict的键添加的实例相同 我认为我在这方面失败了,因为当我尝试使用: if my_object in my_dict: my_dict[my_object]['another_dict_key'].append('Found you!') else: my_dict.update(my_object:{'another_dict_key':[]}) 我想它永远不会出现

我想创建一个自定义类,并使用该类的实例作为dict的键

然后我想创建该类的其他实例,并检查所有属性是否与作为该dict的键添加的实例相同

我认为我在这方面失败了,因为当我尝试使用:

if my_object in my_dict:
    my_dict[my_object]['another_dict_key'].append('Found you!')
else:
    my_dict.update(my_object:{'another_dict_key':[]})
我想它永远不会出现在if语句中,因为my_对象永远不会与已经是dict键的“my_对象”实例匹配,因为它们不是完全相同的实例,即使它们具有相同的属性-

我在其他帖子中读了一些关于这个和散列eq的东西,但我仍然感到困惑。我觉得也许有一种简单的方法可以做到这一点,或者我可以尝试一种完全不同的方法。但是我想问

这是对代码的更全面的了解,我在上面粘贴的代码片段只是为了在某种程度上隔离问题,这里是对它的更深入的了解,我想,如果这有帮助的话,顺便说一下:

master_dict = {}
i = 0
for order in orders:

    normalized_structure = Normalized_Structure(order)
    if normalized_structure in master_dict:
        if 'ORD_INSTRUCTIONS' in master_dict[normalized_structure]:
            master_dict[normalized_structure]['ORD_INSTRUCTIONS'].append(Normalized_Order_Instructions(order))
        else:
            master_dict[normalized_structure]['ORD_INSTRUCTIONS'] = Normalized_Order_Instructions(order)
    else:
        master_dict.update({normalized_structure:{'STRUCTURE_ID':i, 'ORD_INSTRUCTIONS':[]}})
        master_dict[normalized_structure]['ORD_INSTRUCTIONS'].append(Normalized_Order_Instructions())

我认为通常最好写出每个属性,并对其进行比较,但对于20个属性,您可能需要更灵活、更简单的方法。因此,对于平等性检查,您可以

def __eq__(self, other):
    return isinstance(other, type(self)) and all(v == getattr(other, k)
                                                 for k, v in vars(self).items())
至于散列,这取决于您希望采用哪种方法

def __hash__(self):
    result = 1
    for k, v in sorted(vars(self).items()):
        result = 31 * result + hash(v) # chosen prime is 31
    return result
或者,您可以为每个值创建一个元组并对其进行散列

def __hash__(self):
    return hash(tuple(v for k, v in sorted(vars(self).items())))
更新:

如果您的某些属性是不可破坏的,那么您可以像这样忽略它们

def __hash__(self):
    return hash(tuple(v for k, v in sorted(vars(self).items())
                      if getattr(v, '__hash__') is not None))

否则,采用第一种方法并处理它们如何在循环中进行散列。

Hi Steven的可能重复,我查看了这一点,但不确定如何在不设置散列/eq的情况下完成此操作,而不费力地列出每个属性。对于一个有20个属性的类,有没有一种快捷方式可以使它更合理呢?我想你可以做
def\uuuuu eq\uuuu(self,other):为k返回all(v==getattr(other,k),v in vars(self).items())
以及类似的哈希操作,查看如何实现自定义哈希。不过,您可能只需要一些简单的内容。例如,当您说一个类似的/简单的哈希时,您甚至可能会像在这个答案中一样返回0?有没有一个像你在上面写的那样光滑的单行线可以用散列方式工作?谢谢-我是新手…stackoverflow.com/questions/4005318/how-to-implement-a-good-hash-function-in-pythonthank非常感谢你。现在测试。我将不得不跳过self.items()中的几个变量,它们是dicts,它们抛出了不可修复的错误。但我提前知道它们的名称,我想可以直接跳过它们。现在测试..更新了不可破坏值的答案。我必须进行更彻底的测试(可能明天),但目前在轻度测试后,您的解决方案似乎有效,非常感谢您的解释/提供选项。