如果您不修改X
创建后的实例,为什么不子类化元组?
但我要指出,这实际上不会引发错误,至少在 Python 2.6 中是这样。
>>> class X(list):
... __hash__ = tuple.__hash__
... __eq__ = tuple.__eq__
...
>>> x = X()
>>> s = set((x,))
>>> s
set([[]])
我犹豫要不要说“有效”,因为这并不像你认为的那样。
>>> a = X()
>>> b = X((5,))
>>> hash(a)
4299954584
>>> hash(b)
4299954672
>>> id(a)
4299954584
>>> id(b)
4299954672
它只是使用对象 id 作为哈希。当您实际调用时__hash__
,您仍然会收到错误消息;同样对于__eq__
.
>>> a.__hash__()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: descriptor '__hash__' for 'tuple' objects doesn't apply to 'X' object
>>> X().__eq__(X())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: descriptor '__eq__' for 'tuple' objects doesn't apply to 'X' object
我收集到 python 内部,出于某种原因,正在检测X
有一个__hash__
和一个__eq__
方法,但没有调用它们。
这一切的寓意是:只需编写一个真正的哈希函数。由于这是一个序列对象,因此将其转换为元组和散列是最明显的方法。
def __hash__(self):
return hash(tuple(self))