Pourquoi ne puis-je pas appeler hash() sur une méthode apparemment hachable d'une instance indéchiffrable?

disons que j'ai un dictionnaire:

>>> d = {}

Il a une méthode clear():

>>> d.clear
<built-in method clear of dict object at 0x7f209051c988>

... qui a un __hash__ l'attribut:

>>> d.clear.__hash__
<method-wrapper '__hash__' of builtin_function_or_method object at 0x7f2090456288>

... qui est appelable:

>>> callable(d.clear.__hash__)
True

alors pourquoi je ne peux pas le hash?

>>> hash(d.clear)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'

Remarque: je sais que dict les objets sont indéchiffrables – je suis curieux de savoir pourquoi cette restriction s'étend à leurs méthodes, même si, comme indiqué ci-dessus, ils semblent prétendre le contraire?

25
demandé sur Zero Piraeus 2015-03-24 20:26:22
la source

2 ответов

C'est une méthode liée, et les méthodes liées avoir une référence à self, par exemple, le dictionnaire. Cela rend la méthode impraticable.

Vous hash indépendant dict.clear méthode:

>>> 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

Méthodes sur les instances qui hashable seront eux-mêmes hashable, de sorte que le type d'objet intégré dans les méthodes liées met en œuvre un __hash__ méthode, mais soulève TypeError lors de la __self__ attribut n'est pas hachable. Ceci est cohérent avec l' object.__hash__ documentation de la méthode; si vous pouvez le configurer pour None ou de ne pas la mettre en œuvre à tous, alors c'est préférable, mais pour ces cas où la hashability n'est connue qu'à l'exécution élever un TypeError est la seule option disponible.

33
répondu Martijn Pieters 2015-03-24 21:03:36
la source

Martijn a raison comme il a souvent raison. Si vous avez un dict sous-classe qui met en oeuvre le __hash__ méthode, même les méthodes liées devenir hashable

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

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

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

Sortie:

{} 42 287254
Traceback (most recent call last):
  File "y.py", line 9, in <module>
    print(hash(y.clear))
TypeError: unhashable type: 'dict'
11
répondu Antti Haapala 2015-03-24 23:19:32
la source

Autres questions sur