Direkt zum Hauptinhalt springen
eLearner.app
Modul 7 · Lektion 3 von 427/36 im Kurs~12 min
Lektionen des Moduls (3/4)

Spezielle Methoden (Dunder)

Spezialmethoden (auch Dunder-Methoden genannt, weil sie mit einem doppelten Unterstrich beginnen und enden: __name__) sind die Schnittstellen, über die sich deine Objekte in die Sprache integrieren lassen: Textdarstellung, Vergleich mit ==, Unterstützung für len(), in, Operatoren usw.

Eine hast du bereits verwendet: __init__.

__str__ und __repr__

Sie steuern, was bei print() und im REPL angezeigt wird.

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

    def __repr__(self):
        return f"Punto({self.x}, {self.y})"

    def __str__(self):
        return f"({self.x}, {self.y})"

p = Punto(3, 4)
str(p)        # '(3, 4)'        — für Menschen
repr(p)       # 'Punto(3, 4)'   — für Debugger / Entwickler
print(p)      # '(3, 4)'
p             # Punto(3, 4)     im REPL → repr
[p, p]        # [Punto(3, 4), Punto(3, 4)]   — in Containern immer repr

Wenn du nur __repr__ definierst, verwendet Python dieses auch als Fallback für __str__.

__eq__: Neudefinition von ==

Standardmäßig vergleicht a == b die Identitäten der Objekte (is), nicht deren Inhalt. Für einen strukturellen Vergleich definiere __eq__:

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

    def __eq__(self, other):
        if not isinstance(other, Punto):
            return NotImplemented
        return (self.x, self.y) == (other.x, other.y)

Punto(1, 2) == Punto(1, 2)    # True
Punto(1, 2) == Punto(3, 4)    # False

Die Rückgabe von NotImplemented (ein spezielles Schlüsselwort, nicht False!), wenn die Typen nicht vergleichbar sind, ist die korrekte Praxis: Python versucht es dann mit dem __eq__ des anderen Operanden.

__len__: Unterstützung für len()

Python
class Cesto:
    def __init__(self):
        self.frutti = []

    def __len__(self):
        return len(self.frutti)

c = Cesto()
c.frutti.append("mela")
len(c)        # 1
bool(c)       # True (len > 0)

Durch das Definieren von __len__ erhältst du den Boolean-Wert umsonst: Ein Objekt mit len() == 0 wird als Falsy gewertet.

Weitere nützliche Dunder-Methoden (Übersicht)

  • __add__(self, other) → definiert + neu
  • __lt__, __le__, __gt__, __ge__ → Vergleichsoperatoren
  • __contains__(self, item) → unterstützt item in self
  • __iter__ + __next__ → macht das Objekt iterierbar
  • __getitem__(self, key) → unterstützt self[key]
  • __hash__ → erforderlich, um ein Dictionary-Schlüssel / Set-Element zu sein

Probiere es aus

Übung#python.m7.l3.e1
Versuche: 0Wird geladen…

Definiere `Money` mit __init__(self, amount, currency) und __str__, das `f'{amount} {currency}'` zurückgibt. Erstelle `s = Money(42, 'EUR')` und evaluiere `str(s)`.

Editor wird geladen…
Hinweis anzeigen

f-String in __str__.

Lösung nach 3 Versuchen verfügbar

Wiederholungsübung

Übung#python.m7.l3.e2
Versuche: 0Wird geladen…

Definiere `Pair` mit __init__(self, a, b) and __eq__ basierend auf dem strukturellen Vergleich von (a, b). Evaluiere `Pair(1, 2) == Pair(1, 2)`.

Editor wird geladen…
Hinweis anzeigen

Vergleiche die Tupel (self.a, self.b) == (other.a, other.b).

Lösung nach 3 Versuchen verfügbar

Zusätzliche Herausforderung

Übung#python.m7.l3.e3
Versuche: 0Wird geladen…

Definiere eine Klasse `Book` mit einem Konstruktor, der `title` und `author` entgegennimmt. Definiere die Spezialmethode `__str__(self)` so, dass sie den String `"Title by Author"` zurückgibt (z.B. `'1984 by George Orwell'`). Instanziiere ein Buch und evaluiere `str(book)`.

Editor wird geladen…
Hinweis anzeigen

Verwende f"{self.title} by {self.author}" innerhalb von def __str__(self):.

Lösung nach 3 Versuchen verfügbar