Die Python-Funktion hash(obj) berechnet einen Integer-Hash-Wert eines hashable Objekts. Hash-Werte sind das Fundament für dict- und set-Lookups in O(1). Custom-Klassen können __hash__() implementieren — und müssen dann auch __eq__() konsistent dazu definieren.

Einleitung

Die Hash-Funktion bildet ein Objekt auf eine ganze Zahl ab. Python nutzt sie als Index in Hash-Tabellen (dict, set) — daher müssen dict-Keys und set-Elemente hashable sein.

Zwei Regeln müssen Custom-Klassen einhalten:

  1. Konsistenz mit __eq__: a == b muss hash(a) == hash(b) implizieren.
  2. Stabilität über die Lebenszeit: Der Hash darf sich nicht ändern, solange das Objekt existiert.

Daher sind mutable Objekte (Listen, Dicts) standardmäßig nicht hashable — ihr Hash könnte sich nach Mutation ändern und Hash-Tabellen kaputtmachen.

Strings, Zahlen, Tupel (mit hashable Inhalt) und frozenset sind hashable. Custom-Klassen sind hashable, sobald __hash__ definiert ist (oder object-Default greift).

Syntax

Python Syntax
hash(object)
Parameter
object

Ein hashable Objekt.

Rückgabewert

Eine int. Bei nicht hashable Objekten: TypeError.

Beispiele

Standard-Typen

Hashes von Builtins lassen sich direkt anschauen — die konkreten Werte sind in CPython per Hash-Randomization meist pro Prozess unterschiedlich:

Python Beispiel
print(hash(42))
print(hash(3.14))
print(hash("hallo"))
print(hash((1, 2, 3)))
print(hash(None))
Output
42
322818021289917443
...  (zufällig pro Prozess)
529344067295497451
0

Nicht hashable

Mutable Container sind nicht hashable und werfen TypeError:

Python Beispiel
try:
    hash([1, 2, 3])
except TypeError as e:
    print(e)
try:
    hash({"a": 1})
except TypeError as e:
    print(e)
Output
unhashable type: 'list'
unhashable type: 'dict'

Custom-Klasse mit hash und eq

Wer eine eigene Klasse hashable machen will, muss BEIDE Methoden konsistent implementieren:

Python Beispiel
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __eq__(self, other):
        return isinstance(other, Point) and (self.x, self.y) == (other.x, other.y)

    def __hash__(self):
        return hash((self.x, self.y))

p1 = Point(1, 2)
p2 = Point(1, 2)
print(p1 == p2)
print(hash(p1) == hash(p2))
print({p1, p2})    # nur ein Element
Output
True
True
{<...Point object at 0x...>}

Praktische Beispiele

Hash-basierte Deduplizierung

hash() ist die Basis dafür, dass set() Duplikate erkennt — alles, was hashable ist, lässt sich so deduplizieren:

Python Beispiel
items = [(1, 2), (3, 4), (1, 2), (5, 6)]
unique = set(items)
print(unique)
Output
{(1, 2), (3, 4), (5, 6)}

Dataclass mit eq=True (Default) ist hashable nur mit frozen=True

Dataclasses bekommen __eq__ automatisch — __hash__ aber nur, wenn frozen=True gesetzt ist:

Python Beispiel
from dataclasses import dataclass

@dataclass(frozen=True)
class User:
    name: str
    age: int

u = User("Michael", 34)
print(hash(u))
print({u, User("Michael", 34)})   # Set mit nur einem Element
Output
...
{User(name='Michael', age=34)}

Praktische Hinweise

  • Hash ist KEIN kryptografischer Hash — er ist auf Geschwindigkeit und Verteilung optimiert, nicht auf Sicherheit. Für Security: hashlib.
  • Hash-Randomization: String- und Bytes-Hashes ändern sich pro Prozess (gegen Hash-Flooding-DoS).
  • __hash__ = None setzen in einer Klasse macht Instanzen explizit unhashable (sinnvoll für mutable Klassen mit __eq__).
  • Konsistenz: Wenn __eq__ implementiert ist, MUSS auch __hash__ definiert sein (oder explizit auf None) — sonst bricht das Set/Dict-Verhalten.
  • Verwandte Module: hashlib (kryptografische Hashes), hmac, functools.lru_cache (nutzt hash intern).
/ Weiter

Zurück zu Builtin Functions

Zur Übersicht