Łatwo zobaczyć, że opcja nr 3 odnosi się do zdefiniowanych przez użytkownika obiektów. Pozwala to zmienić mieszanie, jeśli zmienisz obiekt, ale jeśli kiedykolwiek użyjesz tego obiektu jako klucza słownika, musisz się upewnić, że hasz się nie zmienia.
>>> class C:
def __hash__(self):
print("__hash__ called")
return id(self)
>>> inst = C()
>>> hash(inst)
__hash__ called
43795408
>>> hash(inst)
__hash__ called
43795408
>>> d = { inst: 42 }
__hash__ called
>>> d[inst]
__hash__ called
Opcja użycia ciągów # 2: obliczają wartość skrótu raz i buforują wynik. Jest to bezpieczne, ponieważ łańcuchy są niezmienne, więc skrót nie może się nigdy zmienić, ale jeśli podklasa str
wynik może nie być niezmienny, więc metoda __hash__
będzie wywoływana za każdym razem. Krotki są zwykle uważane za niezmienne, więc możesz pomyśleć, że hash może być zbuforowany, ale w rzeczywistości krotka krotka zależy od skrótu jej zawartości i może zawierać zmienne wartości.
Dla @max którzy nie wierzą, że podklasy str
można zmodyfikować skrót:
>>> class C(str):
def __init__(self, s):
self._n = 1
def __hash__(self):
return str.__hash__(self) + self._n
>>> x = C('hello')
>>> hash(x)
-717693723
>>> x._n = 2
>>> hash(x)
-717693722
3 jest obecnie jak mam [czytaj] (http://www.laurentluce.com/posts/ python-dictionary-implementation /) jest buforowany przy pierwszym wywołaniu.Zakładam, że druga opcja jest właściwa, ale ponieważ nie jestem pewien, nie będę go publikować jako odpowiedzi :) – rplnt
@rplnt: wrong; to tylko po rozmowie ze słownikiem. Jego skrót zostanie zapisany w słowniku, ale nie dotyczy to ogólnego skrótu. –
@ChrisMorgan Właściwie nie uważam, że Python 'dict' buforuje wartości mieszania dla swoich kluczy. Oczywiście poszczególne klasy mogą robić, co im się podoba w funkcji '__hash__', więc artykuł, o którym mowa powyżej, powiedział, że' str' buforuje swoje wartości mieszania. – max