EMZETT.
Login

Kurz: Methoden mit doppelten Unterstrichen wie init heißen Dunder-Methoden (double underscore) oder magische Methoden. Python ruft sie automatisch auf, wenn du Operatoren und eingebaute Funktionen auf deine Objekte anwendest.

Teil des Kurses Python

Kapitel 38 von 44 im Kurs Python. Mit Fortschritt, Quiz und Zertifikat auf der Lernseite.

Methoden mit doppelten Unterstrichen wie __init__ heißen Dunder-Methoden (double underscore) oder magische Methoden. Python ruft sie automatisch auf, wenn du Operatoren und eingebaute Funktionen auf deine Objekte anwendest. So verhalten sich eigene Klassen wie eingebaute Typen.

Überblick

MethodeWird aufgerufen bei
__init__Klasse(...)
__str__, __repr__str(x), print(x), repr(x)
__len__len(x)
__getitem__x[i]
__contains__a in x
__iter__, __next__for a in x
__add__, __sub__, __mul__x + y, x - y, x * y
__eq__, __lt__x == y, x < y
__bool__if x:
__call__x(...)
__enter__, __exit__with x:

Rechnen mit eigenen Objekten

class Vektor:
    def __init__(self, x, y):
        self.x, self.y = x, y
 
    def __add__(self, o):
        return Vektor(self.x + o.x, self.y + o.y)
 
    def __mul__(self, k):
        return Vektor(self.x * k, self.y * k)
 
    def __eq__(self, o):
        return (self.x, self.y) == (o.x, o.y)
 
    def __repr__(self):
        return f"Vektor({self.x}, {self.y})"
 
a, b = Vektor(1, 2), Vektor(3, 4)
print(a + b)
print(a * 3)
print(a + b == Vektor(4, 6))

Ausgabe:

Vektor(4, 6)
Vektor(3, 6)
True

Sich wie eine Sammlung verhalten

class Regal:
    def __init__(self, *buecher):
        self.buecher = list(buecher)
 
    def __len__(self):
        return len(self.buecher)
 
    def __getitem__(self, i):
        return self.buecher[i]
 
    def __contains__(self, titel):
        return titel in self.buecher
 
r = Regal("Faust", "Momo", "Ronja")
print(len(r), r[1], "Momo" in r)
for buch in r:                 # funktioniert dank __getitem__
    print("-", buch)

Ausgabe:

3 Momo True
- Faust
- Momo
- Ronja

Vergleichen und Sortieren

Mit __lt__ lassen sich Objekte sortieren. Der Dekorator functools.total_ordering ergänzt die restlichen Vergleiche:

from functools import total_ordering
 
@total_ordering
class Version:
    def __init__(self, text):
        self.teile = tuple(int(t) for t in text.split("."))
 
    def __eq__(self, o):
        return self.teile == o.teile
 
    def __lt__(self, o):
        return self.teile < o.teile
 
    def __repr__(self):
        return "v" + ".".join(map(str, self.teile))
 
liste = [Version("1.10.0"), Version("1.2.5"), Version("1.2.10")]
print(sorted(liste))
print(max(liste), Version("2.0") >= Version("1.9"))

Ausgabe:

[v1.2.5, v1.2.10, v1.10.0]
v1.10.0 True

Aufrufbare Objekte

class Verdoppler:
    def __init__(self, faktor=2):
        self.faktor = faktor
 
    def __call__(self, x):
        return x * self.faktor
 
dopple = Verdoppler()
print(dopple(21))
print(list(map(Verdoppler(10), [1, 2, 3])))

Ausgabe:

42
[10, 20, 30]

Kontext-Manager

Mit __enter__ und __exit__ kannst du eigene with-Blöcke bauen, genau wie bei Dateien:

class Abschnitt:
    def __init__(self, name):
        self.name = name
 
    def __enter__(self):
        print(f"--- {self.name} beginnt")
        return self
 
    def __exit__(self, typ, wert, spur):
        print(f"--- {self.name} endet")
        return False        # Fehler nicht verschlucken
 
with Abschnitt("Test"):
    print("mittendrin")

Ausgabe:

--- Test beginnt
mittendrin
--- Test endet

Merke

  • Dunder-Methoden werden von Python automatisch aufgerufen
  • __add__, __eq__, __lt__ & Co. überladen Operatoren
  • __len__, __getitem__, __contains__ machen Objekte zu Sammlungen
  • __call__ macht Objekte aufrufbar
  • __enter__/__exit__ bauen eigene with-Blöcke
  • @total_ordering spart Vergleichsmethoden

Übungsaufgabe

Baue eine Klasse Geld mit Betrag und Währung, die sich addieren und vergleichen lässt und schön ausgibt (zum Beispiel 12.50 EUR).

Quiz zur Selbstkontrolle

Weiter im Kurs

Zurück: Vererbung und Polymorphie

Weiter: Dataclasses und Properties

Alle Kapitel: Python im Überblick