Operator Overloading in Python meistern: Ein praktischer Leitfaden
Python Operator Overloading
Entdecken Sie, wie Sie Operatorverhalten in Python mit speziellen Methoden wie __add__, __lt__ und mehr neu definieren, um Ihre OOP-Designs zu verbessern.
Python Operator Overloading
Pythons eingebaute Operatoren verhalten sich je nach Operandentypen unterschiedlich. Der +-Operator addiert beispielsweise Zahlen, verkettet Strings oder mergt Listen. Diese Flexibilität wird durch Operator Overloading erreicht – ein Feature, das es Ihnen erlaubt, kontextspezifische Bedeutungen für Operatoren Ihrer eigenen Klassen zuzuweisen.
Betrachten Sie eine einfache Punkt-Klasse, die eine Koordinate in einer 2D-Ebene repräsentiert. Ohne spezielle Methoden wird der Versuch, zwei Punkte zu addieren, einen TypeError auslösen:
class Punkt:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
p1 = Punkt(1, 2)
p2 = Punkt(2, 3)
print(p1+p2)
Ausgabe
Traceback (most recent call last): File "<string>", line 9, in <module> print(p1+p2) TypeError: unsupported operand type(s) for +: 'Punkt' and 'Punkt'
Da Python kein eingebautes Wissen darüber hat, wie zwei Punkt-Instanzen zu kombinieren sind, wirft es eine Exception. Operator Overloading lässt uns dieses Verhalten selbst definieren.
Python Spezielle Methoden
Methoden, die von doppelten Unterstrichen umgeben sind – __init__, __str__, __add__ usw. – werden als spezielle Methoden oder "Dunder"-Methoden bezeichnet. Sie werden implizit von Pythons Runtime aufgerufen und sind die Anknüpfungspunkte für Operator Overloading, Container-Protokolle und mehr.
Zum Beispiel steuert die __str__-Methode, wie ein Objekt in einen menschenlesbaren String konvertiert wird. Standardmäßig zeigt das Drucken eines Objekts seine Speicheradresse an, was oft nicht nützlich ist. Das Überschreiben von __str__ kann Debugging und Logging weitaus klarer machen:
class Punkt:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __str__(self):
return '({0}, {1})'.format(self.x, self.y)
Jetzt erhalten wir beim Drucken eines Punkt:
p1 = Punkt(2, 3)
print(p1)
Ausgabe
(2, 3)
Dieselbe Darstellung wird von str(p1) und format(p1) verwendet, da Python intern p1.__str__() aufruft.
Den + Operator überladen
Um die Addition für Punkt-Objekte anzupassen, implementieren Sie __add__:
class Punkt:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __str__(self):
return '({0}, {1})'.format(self.x, self.y)
def __add__(self, other):
return Punkt(self.x + other.x, self.y + other.y)
Testen des neuen Verhaltens:
p1 = Punkt(1, 2)
p2 = Punkt(2, 3)
print(p1 + p2)
Ausgabe
(3, 5)
Unter der Haube führt Python p1.__add__(p2) aus, was einen frischen Punkt mit den summierten Koordinaten zurückgibt.
Nachfolgend eine Schnellreferenz für andere arithmetische Operatoren und die speziellen Methoden, die Sie implementieren müssen:
| Operator | Ausdruck | Spezielle Methode |
|---|---|---|
| Addition | p1 + p2 | __add__(self, other) |
| Subtraktion | p1 - p2 | __sub__(self, other) |
| Multiplikation | p1 * p2 | __mul__(self, other) |
| Potenz | p1 ** p2 | __pow__(self, other) |
| Division | p1 / p2 | __truediv__(self, other) |
| Ganzzahl-Division | p1 // p2 | __floordiv__(self, other) |
| Modulo | p1 % p2 | __mod__(self, other) |
| Links-Shift | p1 << p2 | __lshift__(self, other) |
| Rechts-Shift | p1 >> p2 | __rshift__(self, other) |
| Bitweises UND | p1 & p2 | __and__(self, other) |
| Bitweises ODER | p1 | p2 | __or__(self, other) |
| Bitweises XOR | p1 ^ p2 | __xor__(self, other) |
| Bitweises NICHT | ~p1 | __invert__(self) |
Vergleichsoperatoren überladen
Operator Overloading ist nicht auf Arithmetik beschränkt. Vergleichsoperatoren können ebenfalls angepasst werden. Zum Beispiel, um Punkte basierend auf ihrer Entfernung vom Ursprung zu vergleichen, überschreiben Sie __lt__:
class Punkt:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __str__(self):
return '({0}, {1})'.format(self.x, self.y)
def __lt__(self, other):
self_mag = self.x**2 + self.y**2
other_mag = other.x**2 + other.y**2
return self_mag < other_mag
Verwendung:
p1 = Punkt(1, 1)
p2 = Punkt(-2, -3)
p3 = Punkt(1, -1)
print(p1 < p2) # True
print(p2 < p3) # False
print(p1 < p3) # False
Andere Vergleichsmethoden folgen einem ähnlichen Muster:
| Operator | Ausdruck | Spezielle Methode |
|---|---|---|
| Kleiner als | p1 < p2 | __lt__(self, other) |
| Kleiner oder gleich | p1 <= p2 | __le__(self, other) |
| Gleich | p1 == p2 | __eq__(self, other) |
| Ungleich | p1 != p2 | __ne__(self, other) |
| Größer als | p1 > p2 | __gt__(self, other) |
| Größer oder gleich | p1 >= p2 | __ge__(self, other) |
Durch sorgfältiges Definieren dieser Methoden können Sie benutzerdefinierte Objekte natürlich an arithmetischen und Vergleichskontexten teilnehmen lassen, wodurch Codelesbarkeit und Wartbarkeit verbessert werden.
Python
- Python-Datentypen meistern: Praxisleitfaden
- Python-Operatoren meistern: Umfassender Leitfaden
- Python pass-Statement meistern: Praxisleitfaden
- Python-Funktionsargumente meistern: Positional, Keyword & Default-Parameter
- Python-Dictionaries meistern: Erstellung, Manipulation und fortgeschrittene Techniken
- Python Vererbung meistern: Konzepte, Syntax und praktische Beispiele
- Python Iteratoren meistern: Funktionsweise und Erstellung eigener Iteratoren
- Python Closures erklärt: Wie verschachtelte Funktionen Variablen erfassen
- Pythons @property Decorator meistern: Saubere, rückwärtskompatible Getter & Setter
- Python datetime meistern: Praktischer Leitfaden zu Datumsangaben, Zeiten und Zeitzonen