Überladen des Python-Operators

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 TypeErrorausgelöst wurde, da Python nicht wusste, wie man zwei PointObjekte 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 PointObjekts 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 PointObjekt 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 PointKlasse 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)

Interessante Beiträge...