Zum Inhalt

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