我们说我有一本字典:
>>> d = {}
它有一个方法clear()
:
>>> d.clear
<built-in method clear of dict object at 0x7f209051c988>
...具有__hash__
属性:
>>> d.clear.__hash__
<method-wrapper '__hash__' of builtin_function_or_method object at 0x7f2090456288>
...可以赎回:
>>> callable(d.clear.__hash__)
True
那为什么我不能哈希呢?
>>> hash(d.clear)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'
注意:我知道dict
个对象不可用 - 我很好奇为什么这个限制扩展到他们的方法,即使如上所述,它们似乎否则要求?
答案 0 :(得分:33)
这是一种绑定方法,绑定方法可以引用self
,例如词典。这使得该方法不可清除。
您可以哈希未绑定的dict.clear
方法:
>>> d = {}
>>> d.clear.__self__
{}
>>> d.clear.__self__ is d
True
>>> hash(d.clear)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'
>>> hash(dict.clear)
-9223372036586189204
hashable的实例上的方法本身是可散列的,因此内置绑定方法的对象类型实现__hash__
方法,但在{{TypeError
时引发__self__
1}}属性不可清除。这与object.__hash__
方法文档一致;如果您可以将其设置为None
或根本不实现它,那么这是优选的,但对于仅在运行时已知可用性的情况,提出TypeError
是唯一可用的选项。
答案 1 :(得分:11)
dict
子类确实实现了__hash__
方法,那么即使绑定方法也变得可以使用
class MyHashableDict(dict):
def __hash__(self):
return 42
x = MyHashableDict()
print(x, hash(x), hash(x.clear))
y = {}
print(y, hash(y.clear))
输出:
{} 42 287254
Traceback (most recent call last):
File "y.py", line 9, in <module>
print(hash(y.clear))
TypeError: unhashable type: 'dict'