为什么我不能对一个不易损坏的实例的一个明显可哈希的方法调用hash()?

2024-04-25 03:41:35 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有一本字典:

>>> d = {}

它有一个方法clear()

^{pr2}$

。。。具有__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对象是不可损坏的——我很好奇为什么这个限制会扩展到它们的方法,尽管如上所述,它们似乎声称不是这样的?在


Tags: orof方法字典属性objectfunctionhash
2条回答

马蒂恩是对的,因为他经常是对的。如果您有一个实现dict方法的dict子类,那么即使是绑定的方法也可以是散列的

class MyHashableDict(dict):
    def __hash__(self):
        return 42

x = MyHashableDict()
print(x, hash(x), hash(x.clear))

y = {}
print(y, hash(y.clear))

输出:

^{pr2}$

它是一个绑定方法,绑定方法引用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

散列的实例上的方法本身也是散列的,因此内置绑定方法的对象类型实现了一个__hash__方法,但在__self__属性不可哈希时引发{}。这与object.__hash__方法文档是一致的;如果您可以将其设置为None或根本不实现它,那么这是更好的选择,但是对于只有在运行时才知道哈希性的情况下,引发一个TypeError是唯一可用的选项。在

相关问题 更多 >