根据 this page , set.intersection 使用 __eq__
方法测试元素是否相等。谁能向我解释为什么这会失败?
>>> Class Foo(object):
>>> def __eq__(self, other):
>>> return True
>>>
>>> set([Foo()]).intersection([Foo()])
set([])
使用 2.7.3。是否有另一种(不太复杂)的方法来做到这一点?
最佳答案
如果您覆盖 __eq__
,您也应该始终覆盖 __hash__
。
"If a == b, then it must be the case that hash(a) == hash(b), else sets and dictionaries will fail." Eric
__hash__
用于从对象中生成整数。
这用于将字典的键或集合的元素放入桶中,以便可以更快地找到它们。
如果您不覆盖 __hash__
,尽管对象相等,但默认算法会创建不同的哈希整数。
在你的情况下我会这样做:
class Foo(object):
def __eq__(self, other):
return type(self) == type(other)
def __hash__(self):
return 1
因为您的类的所有对象都等于该类的所有其他对象,所以它们必须都在集合中的同一个 bucket(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
就决定了相等的含义。
关于Python 设置交集和 __eq__,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17641604/