根据this page,使用__eq__
方法对元素相等性进行set.intersection测试。任何人都可以向我解释为什么会失败吗?
>>> Class Foo(object):
>>> def __eq__(self, other):
>>> return True
>>>
>>> set([Foo()]).intersection([Foo()])
set([])
使用2.7.3。还有另一种(不是过于复杂)的方式吗?
答案 0 :(得分:4)
如果您覆盖__eq__
,也应始终覆盖__hash__
。
"如果a == b,则必须是hash(a)== hash(b),否则设置 和字典会失败。"埃里克
__hash__
用于从对象生成整数。
这用于将字典的键或集合的元素放入桶中,以便更快地找到它们。
如果不覆盖__hash__
,默认算法会创建不同的哈希整数,尽管对象是相等的。
在你的情况下,我会这样做:
class Foo(object):
def __eq__(self, other):
return type(self) == type(other)
def __hash__(self):
return 1
因为你的类的所有对象都等于该类的每个其他对象,所以它们必须都在集合中的同一个桶(1)中。这样in
也会返回True
。
__eq__
应该是什么样的:
如果你只比较Foo对象
def __eq__(self, other):
return self.number == other.number
如果您还将Foo对象与其他对象进行比较:
def __eq__(self, other):
return type(self) == type(other) and self.number == other.number
如果您有不同类别的不同算法,我推荐double-dispatch。
class Foo:
def __eq__(self, other):
return hasattr(other, '_equals_foo') and other._equals_foo(self)
def _equals_foo(self, other):
return self.number == other.number
def _equals_bar(self, other):
return False # Foo never equals Bar
class Bar:
def __eq__(self, other):
return hasattr(other, '_equals_bar') and other._equals_bar(self)
def _equals_foo(self, other):
return False # Foo never equals Bar
def _equals_bar(self, other):
return True # Bar always equals Bar
这样,a
中的b
和a == b
决定了平等的含义。