自定义类对象和“in”集合运算符
我正在使用 Python 3.6。假设我试图保留一组唯一的元组。我知道我可以使用tuple in set并取回正确的结果(该集合是否包含元组)。
s = set()
t1 = (1, 2)
t2 = (1, 2)
s.add(t1)
print(t2 in s) # True -- Great!
现在,假设我有一个包含元组的自定义类。我想将自定义类对象的唯一性定义为元组的唯一性。我做了以下事情:
class TupleWrapper(object):
def __init__(self, t):
self.t = t # tuple
def __hash__(self):
return hash(self.t)
s = set()
t1 = TupleWrapper((1, 2))
s.add(t1)
t2 = TupleWrapper((1, 2))
print(t2 in s) # False -- WHY?
我编写了自己的__hash__()方法来对元组进行哈希处理。那么为什么TupleWrapper没有发现具有相同元组的两个对象在set. 我需要覆盖另一个方法吗?
回答
您需要实现__eq__上TupleWrapper也是如此。
def __eq__(self, other):
if isinstance(other, TupleWrapper):
return self.t == other.t
return NotImplemented
否则,当检查对象是否已经在集合中时,它将默认为身份比较,这只是is(即,t1 is t2或id(t1) == id(t2))。
更多细节:松散地说,在插入时,set(和dict)首先使用散列值来确定哪个桶中的东西。然后,在那个桶中,它使用==,在散列冲突的情况下用来检查该对象是否已经存在那里。
散列文档在这里
- @stackoverflowuser2010 for starters, https://docs.python.org/3/reference/datamodel.html#object.__hash__
- @stackoverflowuser2010: `__eq__` is the overload hook for `==` equality comparisons.
- Thank you. How would I know that `thing in set` would call `thing.__eq__(other)`? Is it documented clearly somewhere?