Почему я не могу вызвать hash() для явно хэшируемого метода неустрашимого экземпляра?
Допустим, у меня есть словарь:
>>> 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 ответа
Это связанный метод, а связанные методы имеют ссылку на 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
это единственный доступный вариант.
Мартейн прав, как он часто бывает. Если у тебя есть 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'