Arten, Definition von `__eq__`, sind unhashable?
Hatte ich einen seltsamen Fehler bei der Portierung einer Funktion, um die Python 3.1-Gabel von meinem Programm. Ich verengt Sie sich auf der folgenden Hypothese:
Im Gegensatz zu Python 2.x, in Python 3.x wenn für ein Objekt ein __eq__
Methode ist es automatisch unhashable.
Ist das wahr?
Hier ist, was passiert in Python 3.1:
>>> class O(object):
... def __eq__(self, other):
... return 'whatever'
...
>>> o = O()
>>> d = {o: 0}
Traceback (most recent call last):
File "<pyshell#16>", line 1, in <module>
d = {o: 0}
TypeError: unhashable type: 'O'
Den follow-up-Frage ist, wie löse ich mein problem? Ich habe ein Objekt ChangeTracker
die speichert eine WeakKeyDictionary
Punkte, die zu mehreren Objekten, wobei für jede den Wert Ihrer Gurke-dump zu einem bestimmten Zeitpunkt in der Vergangenheit. Wenn ein vorhandenes Objekt aktiviert ist, ist die Veränderung tracker sagt, ob seine neue Gurke ist identisch mit seinen alten, deshalb zu sagen, ob das Objekt in der Zwischenzeit geändert. Problem ist, jetzt kann ich auch nicht überprüfen, ob das angegebene Objekt in der Bibliothek, weil es macht es eine Ausnahme auslösen über das Objekt, unhashable. (Ursache es hat eine __eq__
Methode.) Wie kann ich dies umgehen?
__hash__
Methode?
InformationsquelleAutor Ram Rachum | 2009-10-22
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ja, wenn Sie definieren
__eq__
die Standard -__hash__
(nämlich die Vermischung wird die Adresse des Objekts im Speicher) geht Weg. Dies ist wichtig, weil das hashing muss im Einklang mit Gleichheit: gleiche Objekte müssen den gleichen hash -.Die Lösung ist einfach: Sie definieren
__hash__
zusammen mit der Definition__eq__
.__hash__
alsreturn id(self)
.Verwendung von
id(self)
im__hash__()
sicherlich falsch, es sei denn, man definiert__eq__()
zu vergleichen, durch die Objekt-Identität (das scheint sinnlos). Was die Aktualisierung Ihrer Frage mit echten__eq__()
Umsetzung, so dass wir empfehlen__hash__()
zu ergänzen?Ich habe versucht, dieses Problem zu lösen; ich kam mit dieser:
def __eq__(): return self.__dict__ == other.__dict__
unddef __hash__(): return hash(self.__dict__.values())
Dies ist nicht eine gute Antwort - es ist nicht nur die Standard-hash, der geht Weg - es ist alle geerbten hash.
InformationsquelleAutor Martin v. Löwis
Diesem Absatz aus http://docs.python.org/3.1/reference/datamodel.html#object.hash
InformationsquelleAutor newacct
Überprüfen Sie die Python-3-Handbuch auf
- Objekt.__hash__
:Hervorhebung ist von mir.
Wenn Sie wollen, faul zu sein, es klingt wie Sie können einfach definieren
__hash__(self)
zurückid(self)
:return id(self)
hash-Funktion ist defekt (gleiche Objekte müssen den gleichen hash-siehe Martins Antwort). Die "I don ' T care" - hash-Funktion wärereturn 1
. Das ist einfach und erfüllt alle Bedingungen (es ist nur sehr ineffizient!)InformationsquelleAutor Mark Rushakoff
Ich bin kein python-Experte, aber wäre es nicht sinnvoll, dass, wenn Sie definieren ein eq-Methode, müssen Sie auch definieren, eine hash-Methode (berechnet den hash-Wert für ein Objekt) Ansonsten der Hash-Mechanismus nicht kennen würden, wenn Sie auf dasselbe Objekt oder ein anderes Objekt mit dem gleichen hash-Wert. Eigentlich ist es die andere Weise herum, es würde wahrscheinlich am Ende computing verschiedene hash-Werte für die Objekte als gleich betrachtet, die durch Ihre
__eq__
Methode.Ich habe keine Ahnung was das hash-Funktion wird aufgerufen, obwohl
__hash__
vielleicht? 🙂Es ist eigentlich Umgekehrt. Wenn zwei Objekte den gleichen hash-Wert, aber nicht gleich sind - das ist in Ordnung. Die "Hash-Mechanismus" (z.B. das Wörterbuch) überprüft zuerst den hash, und, auf gleiche hash-Werte, auch im Vergleich der Geschlechter. Das eigentliche problem tritt den anderen Weg 'Runde: Objekte hash anders, aber immer noch das gleiche vergleichen. Das Wörterbuch sollte Sie finden, aber nicht (oder bekommen Sie vielleicht doppelte Schlüssel im Wörterbuch).
v. Löwis: ich erkannte, dass, und fügte hinzu, dass am Ende, oder ist es ein feiner Unterschied zu dem, was ich gesagt habe?
InformationsquelleAutor falstro