Sie können die Bedeutung eines Operators in Python abhängig von den verwendeten Operanden ändern. In diesem Tutorial erfahren Sie, wie Sie die Operatorüberladung in der objektorientierten Python-Programmierung verwenden.
Überladen des Python-Operators
Python-Operatoren arbeiten für integrierte Klassen. Der gleiche Operator verhält sich jedoch bei verschiedenen Typen unterschiedlich. Beispielsweise führt der +
Operator eine arithmetische Addition für zwei Zahlen durch, führt zwei Listen zusammen oder verkettet zwei Zeichenfolgen.
Diese Funktion in Python, mit der derselbe Operator je nach Kontext unterschiedliche Bedeutungen haben kann, wird als Operatorüberladung bezeichnet.
Was passiert also, wenn wir sie mit Objekten einer benutzerdefinierten Klasse verwenden? Betrachten wir die folgende Klasse, die versucht, einen Punkt im 2D-Koordinatensystem zu simulieren.
class Point: def __init__(self, x=0, y=0): self.x = x self.y = y p1 = Point(1, 2) p2 = Point(2, 3) print(p1+p2)
Ausgabe
Traceback (letzter Aufruf zuletzt): Datei "", Zeile 9, in gedruckter Form (p1 + p2) TypeError: Nicht unterstützte Operandentypen für +: 'Point' und 'Point'
Hier können wir sehen, dass a TypeError
ausgelöst wurde, da Python nicht wusste, wie man zwei Point
Objekte zusammenfügt.
Wir können diese Aufgabe in Python jedoch durch Überladen von Operatoren erreichen. Aber lassen Sie uns zuerst eine Vorstellung von speziellen Funktionen bekommen.
Python-Sonderfunktionen
Klassenfunktionen, die mit einem doppelten Unterstrich beginnen, __
werden in Python als Sonderfunktionen bezeichnet.
Diese Funktionen sind nicht die typischen Funktionen, die wir für eine Klasse definieren. Die __init__()
oben definierte Funktion ist eine davon. Es wird jedes Mal aufgerufen, wenn wir ein neues Objekt dieser Klasse erstellen.
Es gibt zahlreiche andere spezielle Funktionen in Python. Besuchen Sie Python Special Functions, um mehr darüber zu erfahren.
Mit speziellen Funktionen können wir unsere Klasse mit integrierten Funktionen kompatibel machen.
>>> p1 = Point(2,3) >>> print(p1)
Angenommen, die print()
Funktion soll die Koordinaten des Point
Objekts anstelle der erhaltenen drucken . Wir können __str__()
in unserer Klasse eine Methode definieren , die steuert, wie das Objekt gedruckt wird. Schauen wir uns an, wie wir dies erreichen können:
class Point: def __init__(self, x = 0, y = 0): self.x = x self.y = y def __str__(self): return "((0),(1))".format(self.x,self.y)
Versuchen wir nun die print()
Funktion erneut.
class Point: def __init__(self, x=0, y=0): self.x = x self.y = y def __str__(self): return "((0), (1))".format(self.x, self.y) p1 = Point(2, 3) print(p1)
Ausgabe
(2, 3)
Das ist besser. Es stellt sich heraus, dass dieselbe Methode aufgerufen wird, wenn wir die integrierte Funktion str()
oder verwenden format()
.
>>> str(p1) '(2,3)' >>> format(p1) '(2,3)'
Wenn Sie also str(p1)
oder verwenden format(p1)
, ruft Python die p1.__str__()
Methode intern auf . Daher der Name, Sonderfunktionen.
Kehren wir nun zur Überladung des Bedieners zurück.
Überladen des + Operators
Um den +
Operator zu überladen , müssen wir die __add__()
Funktion in der Klasse implementieren . Mit großer Macht kommt große Verantwortung. Innerhalb dieser Funktion können wir tun, was wir wollen. Es ist jedoch sinnvoller, ein Point
Objekt der Koordinatensumme zurückzugeben.
class Point: 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): x = self.x + other.x y = self.y + other.y return Point(x, y)
Versuchen wir nun noch einmal die Additionsoperation:
class Point: 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): x = self.x + other.x y = self.y + other.y return Point(x, y) p1 = Point(1, 2) p2 = Point(2, 3) print(p1+p2)
Ausgabe
(3,5)
Was tatsächlich passiert, ist, dass wenn Sie verwenden p1 + p2
, Python-Aufrufe, p1.__add__(p2)
was wiederum ist Point.__add__(p1,p2)
. Danach wird der Additionsvorgang wie angegeben ausgeführt.
Ebenso können wir auch andere Operatoren überlasten. Die spezielle Funktion, die wir implementieren müssen, ist unten aufgeführt.
Operator | Ausdruck | Im Inneren |
---|---|---|
Zusatz | p1 + p2 | p1.__add__(p2) |
Subtraktion | p1 - p2 | p1.__sub__(p2) |
Multiplikation | p1 * p2 | p1.__mul__(p2) |
Leistung | p1 ** p2 | p1.__pow__(p2) |
Teilung | p1 / p2 | p1.__truediv__(p2) |
Floor Division | p1 // p2 | p1.__floordiv__(p2) |
Rest (Modulo) | p1 % p2 | p1.__mod__(p2) |
Bitweise Linksverschiebung | p1 << p2 | p1.__lshift__(p2) |
Bitweise Rechtsverschiebung | p1>> p2 | p1.__rshift__(p2) |
Bitweises UND | p1 & p2 | p1.__and__(p2) |
Bitweises ODER | p1 | p2 | p1.__or__(p2) |
Bitweises XOR | p1 p2 | p1.__xor__(p2) |
Bitweise NICHT | ~p1 | p1.__invert__() |
Vergleichsoperatoren überladen
Python beschränkt das Überladen von Operatoren nicht nur auf arithmetische Operatoren. Wir können auch Vergleichsoperatoren überladen.
Angenommen, wir wollten das Symbol "weniger als <
Symbol" in unserer Point
Klasse implementieren .
Vergleichen wir die Größe dieser Punkte vom Ursprung und geben das Ergebnis für diesen Zweck zurück. Es kann wie folgt implementiert werden.
# overloading the less than operator class Point: 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 p1 = Point(1,1) p2 = Point(-2,-3) p3 = Point(1,-1) # use less than print(p1
Output
True False False
Similarly, the special functions that we need to implement, to overload other comparison operators are tabulated below.
Operator Expression Internally
Less than p1 < p2
p1.__lt__(p2)
Less than or equal to p1 <= p2
p1.__le__(p2)
Equal to p1 == p2
p1.__eq__(p2)
Not equal to p1 != p2
p1.__ne__(p2)
Greater than p1> p2
p1.__gt__(p2)
Greater than or equal to p1>= p2
p1.__ge__(p2)