Zum Inhalt springen
BetaEN
Lektion 26 von 35Python

Python · Lektion 26 · 30 Minuten

Spezielle Methoden und @property

Das lernst du

  • Mit __str__ bestimmen, wie print() ein Objekt zeigt
  • Mit __eq__, __lt__ und __add__ Objekte vergleichen und rechnen
  • Mit @property berechnete Eigenschaften schreiben

Objekte, die sich wie eingebaute Typen verhalten

Du kannst Zahlen mit + addieren und mit < vergleichen, und print() zeigt sie hübsch an. Mit speziellen Methoden (sie haben zwei Unterstriche vorne und hinten, deshalb heißen sie auch „Dunder“-Methoden) können deine eigenen Klassen das auch.

str: Wie sieht mein Objekt aus?

Ohne __str__ zeigt print() nur etwas wie <__main__.Punkt object at 0x…>. Mit __str__ bestimmst du den Text selbst:

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

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

p = Punkt(3, 4)
print(p)
print(f"Der Punkt liegt bei {p}.")

Rechnen und vergleichen

a + b ruft in Wirklichkeit a.__add__(b) auf, a == b ruft a.__eq__(b) auf und a < b ruft a.__lt__(b) auf:

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

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

    def __add__(self, anderer):
        return Punkt(self.x + anderer.x, self.y + anderer.y)

    def __eq__(self, anderer):
        return self.x == anderer.x and self.y == anderer.y

print(Punkt(1, 2) + Punkt(10, 20))
print(Punkt(1, 2) == Punkt(1, 2))
Schreibweiseruft auf
print(a), str(a)a.__str__()
a + ba.__add__(b)
a == ba.__eq__(b)
a < ba.__lt__(b)
len(a)a.__len__()

@property: berechnete Eigenschaften

Manche Werte rechnet man lieber aus, statt sie zu speichern. Mit @property sieht eine Methode von außen aus wie eine normale Eigenschaft – ohne Klammern:

class Rechteck:
    def __init__(self, breite, hoehe):
        self.breite = breite
        self.hoehe = hoehe

    @property
    def flaeche(self):
        return self.breite * self.hoehe

r = Rechteck(4, 3)
print(r.flaeche)
r.breite = 10
print(r.flaeche)

Die Fläche passt sich automatisch an, wenn sich die Breite ändert.

Merke: Spezielle Methoden ruft man fast nie selbst auf. Python ruft sie für dich auf, wenn du +, <, print() oder len() benutzt.

Kurz-Check

Bevor es an die Aufgabe geht: Was gibt dieses Programm aus? Tipp deine Vermutung ein – Python rechnet danach nach.

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

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

    def __add__(self, anderer):
        return Punkt(self.x + anderer.x, self.y + anderer.y)


print(Punkt(1, 2) + Punkt(3, 4))

Deine Aufgabe

Jetzt bist du dran

Ergänze die Klasse Zeit (Minuten und Sekunden). print() soll sie wie 2:05 anzeigen (Sekunden immer zweistellig). Zwei Zeiten sollen sich mit + addieren lassen (aus 90 Sekunden wird 1 Minute 30 Sekunden), mit < vergleichen lassen, und die Eigenschaft gesamt (mit @property) soll die Zeit in Sekunden liefern.

class Zeit:
    def __init__(self, minuten, sekunden):
        self.minuten = minuten + sekunden // 60
        self.sekunden = sekunden % 60

    # __str__, @property gesamt, __add__, __lt__


runde1 = Zeit(1, 40)
runde2 = Zeit(0, 85)
print(runde1 + runde2)
print(runde2 < runde1)

Ohne Hinweise gelöst gibt es einen ⭐ auf deiner Fortschrittsseite.

Lösung anzeigen

Versuch es erst selbst – aus Fehlern lernt man am meisten. Hier ist eine mögliche Lösung:

class Zeit:
    def __init__(self, minuten, sekunden):
        self.minuten = minuten + sekunden // 60
        self.sekunden = sekunden % 60

    def __str__(self):
        return f"{self.minuten}:{self.sekunden:02d}"

    @property
    def gesamt(self):
        return self.minuten * 60 + self.sekunden

    def __add__(self, andere):
        return Zeit(0, self.gesamt + andere.gesamt)

    def __lt__(self, andere):
        return self.gesamt < andere.gesamt


runde1 = Zeit(1, 40)
runde2 = Zeit(0, 85)
print(runde1 + runde2)
print(runde2 < runde1)