为什么我不能在一个不可用的实例的一个明显可用的方法上调用hash()?

时间:2015-03-24 17:26:23

标签: python dictionary methods instance hashable

我们说我有一本字典:

>>> 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个对象不可用 - 我很好奇为什么这个限制扩展到他们的方法,即使如上所述,它们似乎否则要求?

2 个答案:

答案 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)

Martijn经常是对的。如果你有一个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'