如果您创建后不修改
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))