Próbuję zrozumieć, co słowniki Pythona muszą robić wewnętrznie, aby zlokalizować klucz. Wydaje mi się, że najpierw zostanie oszacowany hash, a jeśli dojdzie do kolizji, Python będzie iterować przez klawisze, dopóki nie znajdzie takiego, dla którego eq zwraca True. Co sprawia, że zastanawiam się, dlaczego następujący kod działa (kod testowy tylko dla zrozumienia wewnętrzne):Jaka jest kolejność oceny __hash__ i __eq__ dla dict Pythona?
class MyClass(object):
def __eq__(self, other):
return False
def __hash__(self):
return 42
if __name__=='__main__':
o1 = MyClass()
o2 = MyClass()
d = {o1: 'o1', o2: 'o2'}
assert(o1 in d) # 1
assert(d[o1]=='o1') # 2
assert(o2 in d) # 3
assert(d[o2]=='o2') # 4
Gdyby nie słownika być w stanie znaleźć właściwego klucza (powrót albo o1 „” lub „” w obu O2 w przypadkach # 2 i # 4 lub zgłaszając błąd, w zależności od implementacji wewnętrznej). W jaki sposób jest on w stanie wylądować na właściwym kluczu w obu przypadkach, kiedy nigdy nie będzie w stanie poprawnie "zrównać" kluczy (ponieważ eq zwraca False).
Cała dokumentacja Widziałem na mieszania zawsze wspomina hash i eq razem, nigdy cmp, ne etc, które kojarzy mi się te 2 są jedynymi, które odgrywają rolę w tym scenariusz.
tak w swoim przykładzie o1 == o1 zwróci False, ale id (o1) == id (o1) zwróci True? –
Po prostu wypróbowałem i o1 == o1 zwraca False i id (o1) == id (o1) zwraca True –
@TimurRidjanovic: Tak. 'is' jest bezpieczniejszym, a czasami bardziej wydajnym sposobem porównywania tożsamości obiektu. – user2357112