Python Operator Overloading
Table of Contents
Sie können die Bedeutung eines Operators in Python in Abhängigkeit von den verwendeten Operanden ändern. In diesem Lernprogramm lernen Sie, wie Sie die “operator overloading” in der objektorientierten Programmierung von Python verwenden.
Python Operator Overloading
Python operators arbeit für eingebaute Klassen. Aber der gleiche Operator verhält sich bei verschiedenen Typen unterschiedlich.Zum Beispiel die +
Operator führt eine arithmetische Addition auf zwei Zahlen durch, führt zwei Listen zusammen oder verkettet zwei Zeichenketten.
Diese Funktion in Python, die es ermöglicht, dass derselbe Operator je nach Kontext eine andere Bedeutung hat, wird “operator overloading” genannt.
Was passiert also, wenn wir sie mit Objekten einer benutzerdefinierten Klasse verwenden? Betrachten wir die folgende Klasse, die versucht, einen Punkt im 2-D-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)
Output
Traceback (most recent call last): File "<string>", line 9, in <module> print(p1+p2) TypeError: unsupported operand type(s) for +: 'Point' and 'Point'
Hier können wir sehen, dass a TypeError
wurde ausgelöst, da Python nicht wusste, wie man zwei Point
Objekte zusammen.
Wir können diese Aufgabe in Python jedoch durch “operator overloading” erreichen. Aber zuerst wollen wir uns einen Begriff von speziellen Funktionen machen.
Python Special Functions
Klassenfunktionen, die mit doppeltem Unterstrich beginnen __
werden in Python als spezielle Funktionen bezeichnet.
Diese Funktionen sind nicht die typischen Funktionen, die wir für eine Klasse definieren. Die __init__()
Funktion, die wir oben definiert haben, ist eine von ihnen. Sie wird jedes Mal aufgerufen, wenn wir ein neues Objekt dieser Klasse erzeugen.
Es gibt zahlreiche weitere Spezialfunktionen in Python. Besuchen Sie Python Spezialfunktionen um mehr über sie zu erfahren.
Mit speziellen Funktionen können wir unsere Klasse mit eingebauten Funktionen kompatibel machen.
>>> p1 = Point(2,3) >>> print(p1) <__main__.Point object at 0x00000000031F8CC0>
Angenommen, wir wollen print()
dass die Funktion, die Koordinaten des Point
bjekt anstelle dessen, was wir haben. Wir können ein __str__()
methode in unserer Klasse, 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 wieder.
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)
Output
(2, 3)
Das ist besser. Es stellt sich heraus, dass dieselbe Methode aufgerufen wird, wenn wir die eingebaute Funktion verwenden str()
oder format()
.
>>> str(p1) '(2,3)' >>> format(p1) '(2,3)'
Also, wenn Sie verwenden str(p1)
oder format(p1)
, Python ruft intern die p1.__str__()
Methode. Daher der Name, Sonderfunktionen.
Kehren wir nun zum “Operator Overloading” zurück.
Overloading the + Operator
Um die . zu überlasten +
operator, müssen wir implementieren __add__()
Funktion in der Klasse. Mit großer Macht kommt große Verantwortung. Wir können innerhalb dieser Funktion tun, was immer wir wollen. Aber es ist sinnvoller, eine Point
Objekt der Koordinatensumme.
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 die Additionsoperation 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) 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)
Output
(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 die Additionsoperation wie von uns angegeben durchgeführt.
Ebenso können wir andere Operatoren überladen. Die spezielle Funktion, die wir implementieren müssen, ist unten tabellarisch aufgeführt.
Operator | Expression | Internally |
---|---|---|
Addition | p1 + p2 |
p1.__add__(p2) |
Subtraction | p1 - p2 |
p1.__sub__(p2) |
Multiplication | p1 * p2 |
p1.__mul__(p2) |
Power | p1 ** p2 |
p1.__pow__(p2) |
Division | p1 / p2 |
p1.__truediv__(p2) |
Floor Division | p1 // p2 |
p1.__floordiv__(p2) |
Remainder (modulo) | p1 % p2 |
p1.__mod__(p2) |
Bitwise Left Shift | p1 << p2 |
p1.__lshift__(p2) |
Bitwise Right Shift | p1 >> p2 |
p1.__rshift__(p2) |
Bitwise AND | p1 & p2 |
p1.__and__(p2) |
Bitwise OR | p1 | p2 |
p1.__or__(p2) |
Bitwise XOR | p1 ^ p2 |
p1.__xor__(p2) |
Bitwise NOT | ~p1 |
p1.__invert__() |
Overloading Comparison Operators
Python beschränkt das Überladen von Operatoren nicht nur auf arithmetische Operatoren. Wir können auch Vergleichsoperatoren überladen.
Angenommen, wir wollten das Kleiner-als-Symbol implementieren <
symbol in unserem Point
klasse.
Vergleichen wir die “Größenordnung” dieser Punkte vom Ursprung aus und geben das Ergebnis zu diesem 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<p2) print(p2<p3) print(p1<p3)
Output
True False False
In ähnlicher Weise sind die speziellen Funktionen, die wir implementieren müssen, um andere Vergleichsoperatoren zu überladen, unten tabellarisch aufgeführt.
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) |