重写\uuueq_Uu;和\uuuHash_Uuu以比较两个实例的dict属性

2024-06-16 09:35:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在努力理解如何根据每个实例所拥有的底层dict属性正确地比较对象。在

既然我要重写__eq__,我是否也需要重写__hash__?我不知道何时/何地做这件事,真的需要一些帮助。在

我在下面创建了一个简单的示例来说明我遇到的最大递归异常。RegionalCustomerCollection按地理区域组织帐户ID。^如果区域和它们各自的accountid是相等的,则称{}对象是相等的。本质上,所有items()在内容上应该是相等的。在

from collections import defaultdict

class RegionalCustomerCollection(object):

    def __init__(self):
        self.region_accountids = defaultdict(set) 

    def get_region_accountid(self, region_name=None):
        return self.region_accountids.get(region_name, None)

    def set_region_accountid(self, region_name, accountid):
        self.region_accountids[region_name].add(accountid)

    def __eq__(self, other):
        if (other == self):
            return True

        if isinstance(other, RegionalCustomerCollection):
            return self.region_accountids == other.region_accountids

        return False 

    def __repr__(self):
        return ', '.join(["{0}: {1}".format(region, acctids) 
                          for region, acctids 
                          in self.region_accountids.items()])

让我们创建两个对象实例并用一些示例数据填充它们:

^{pr2}$

现在让我们尝试比较这两个实例并生成递归异常:

>>> a == b
... 
RuntimeError: maximum recursion depth exceeded while calling a Python object

Tags: 对象实例nameself区域示例returndef
2条回答

您不需要重写__hash__来比较两个对象(如果需要自定义哈希,即为了提高插入到集合或字典中的性能,就需要重写)。在

此外,这里还有无限递归:

    def __eq__(self, other):
        if (other == self):
            return True

        if isinstance(other, RegionalCustomerCollection):
            return self.region_accountids == other.region_accountids

        return False 

如果两个对象都是RegionalCustomerCollection类型,那么自从==调用__eq__之后,将有无限递归。在

你的对象不应该返回散列,因为它是可变的。如果您将此对象放入词典或集合中,然后再对其进行更改,则可能再也找不到它了。在

要使对象不可损坏,需要执行以下操作:

class MyClass(object):
    __hash__ = None

这将确保对象不易损坏。在

^{pr2}$

这能回答你的问题吗?我怀疑并不是因为您明确地寻找一个散列函数。在

就您收到的RuntimeError而言,这是因为以下行:

    if self == other:
        return True

这会让你进入一个无限递归循环。请尝试以下方法:

    if self is other:
        return True

相关问题 更多 >