Hashable
Die Objekte in einem Set und die Keys in einem Dictionary müssen hashable sein. Deshalb die Frage: Was bedeutet eigentlich hashable?
Im Python Glossary: hashable findet man zum Thema Hashable den folgenden Eintrag:
hashable
An object is hashable if it has a hash value which never changes during its lifetime (it needs a hash() method), and can be compared to other objects (it needs an eq() method). Hashable objects which compare equal must have the same hash value.Hashability makes an object usable as a dictionary key and a set member, because these data structures use the hash value internally.
Most of Python’s immutable built-in objects are hashable; mutable containers (such as lists or dictionaries) are not; immutable containers (such as tuples and frozensets) are only hashable if their elements are hashable. Objects which are instances of user-defined classes are hashable by default. They all compare unequal (except with themselves), and their hash value is derived from their id().
Fazit: soll eine eigene Klasse hashable sein, müssen die Methoden __eq__ und __hash__ geeignet implementiert werden.
Hier eine Tabelle die zeigt, welche Python Operation auf welche Methode einer Klasse delegiert werden:
Operation | Dunder | Rückgabewert |
---|---|---|
a == b | a.__eq__(b) | True/False/NotImplemented |
hash(a) | a.__hash__() | int |
Die Methode __eq__ gibt typischerweise einen von den Werten True, False oder NotImplemented (if objects can't be compared) zurück. Die Defaultimplementierung von __eq__ basiert auf dem is Operator, der die Identity (Funktion id) vergleicht.
Die Defaultimplementierung von __ne__ ruft __eq__ auf und negiert den boolschen Rückgabewert. Hat __eq__ den Rückgabewert NotImplemented, wird dieser auch von __ne__ zurückgegeben.
Bei einer eigenen Implementierung der Methoden __eq__ und __hash__ ist folgendes zu beachten:
Ist a == b dann muss auch hash(a) == hash(b) sein
Ist hash(a) == hash(b) dann kann a == b oder a != b sein
Ist hash(a) != hash(b) dann muss auch a != b sein