为什么我不能在不可散列实例的明显可散列方法上调用 hash()?
Why can't I call hash() on an apparently hashable method of an unhashable instance?
假设我有一本字典:
>>> 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
对象是不可散列的——我很好奇为什么这个限制会扩展到他们的方法,尽管如上所述,他们似乎另有说法?
它是一个绑定方法,绑定方法有对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__
方法但引发 TypeError
当 __self__
属性不可散列时。这与object.__hash__
方法文档一致;如果您可以将它设置为 None
或根本不实现它,那么这是更可取的,但对于这些可哈希性仅在运行时已知的情况,提高 TypeError
是唯一可用的选项。
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'
假设我有一本字典:
>>> 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
对象是不可散列的——我很好奇为什么这个限制会扩展到他们的方法,尽管如上所述,他们似乎另有说法?
它是一个绑定方法,绑定方法有对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__
方法但引发 TypeError
当 __self__
属性不可散列时。这与object.__hash__
方法文档一致;如果您可以将它设置为 None
或根本不实现它,那么这是更可取的,但对于这些可哈希性仅在运行时已知的情况,提高 TypeError
是唯一可用的选项。
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'