Überladen von Python-Operatoren
Ü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 das Überladen von Operatoren in der objektorientierten Programmierung mit Python verwenden.
Überladung des Python-Operators
Python-Operatoren funktionieren für integrierte Klassen. Aber derselbe Operator verhält sich bei verschiedenen Typen unterschiedlich. Zum Beispiel +
Der Operator führt eine arithmetische Addition an zwei Zahlen durch, führt zwei Listen zusammen oder verkettet zwei Strings.
Diese Funktion in Python, die es ermöglicht, dass derselbe Operator je nach Kontext unterschiedliche Bedeutungen hat, wird Operatorüberladung genannt.
Was passiert also, wenn wir sie mit Objekten einer benutzerdefinierten Klasse verwenden? Betrachten wir die folgende Klasse, die versucht, einen Punkt in einem 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)
Ausgabe
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 ein TypeError
wurde ausgelöst, da Python nicht wusste, wie man zwei Point
hinzufügt Objekte zusammen.
Wir können diese Aufgabe jedoch in Python durch Überladen von Operatoren erreichen. Aber lassen Sie uns zuerst eine Vorstellung von Sonderfunktionen bekommen.
Python-Sonderfunktionen
Klassenfunktionen, die mit doppeltem Unterstrich __
beginnen werden in Python spezielle Funktionen genannt.
Diese Funktionen sind nicht die typischen Funktionen, die wir für eine Klasse definieren. Die __init__()
Funktion, die wir oben definiert haben, ist eine davon. Es wird jedes Mal aufgerufen, wenn wir ein neues Objekt dieser Klasse erstellen.
Es gibt zahlreiche weitere Sonderfunktionen in Python. Besuchen Sie Python Special Functions, um mehr darüber 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()
Funktion zum Drucken der Koordinaten von Point
Objekt anstelle dessen, was wir haben. Wir können einen __str__()
definieren Methode in unserer Klasse, die steuert, wie das Objekt gedruckt wird. Sehen 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 es jetzt mit print()
wieder funktionieren.
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 eingebaute Funktion str()
verwenden oder format()
.
>>> str(p1)
'(2,3)'
>>> format(p1)
'(2,3)'
Also, wenn Sie str(p1)
verwenden oder format(p1)
, Python ruft intern den p1.__str__()
auf Methode. Daher der Name Sonderfunktionen.
Kommen wir nun zurück zum Überladen von Operatoren.
Überladen des Operators +
Um den +
zu überladen -Operator müssen wir __add__()
implementieren Funktion in der Klasse. Mit großer Macht kommt große Verantwortung. Wir können innerhalb dieser Funktion tun, was wir wollen. Sinnvoller ist es aber, eine Point
zurückzugeben 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)
Lassen Sie uns nun die Additionsoperation erneut versuchen:
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 das, wenn Sie p1 + p2
verwenden , Python ruft p1.__add__(p2)
auf was wiederum Point.__add__(p1,p2)
ist . Danach wird die Additionsoperation so ausgeführt, wie wir es angegeben haben.
Ebenso können wir auch andere Operatoren überladen. Die spezielle Funktion, die wir implementieren müssen, ist unten tabelliert.
Operator | Ausdruck | Intern |
---|---|---|
Zusatz | p1 + p2 | p1.__add__(p2) |
Subtraktion | p1 - p2 | p1.__sub__(p2) |
Multiplikation | p1 * p2 | p1.__mul__(p2) |
Macht | p1 ** p2 | p1.__pow__(p2) |
Abteilung | p1 / p2 | p1.__truediv__(p2) |
Etagenaufteilung | p1 // p2 | p1.__floordiv__(p2) |
Rest (modulo) | p1 % p2 | p1.__mod__(p2) |
Bitweise Verschiebung nach links | 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__() |
Überladen von Vergleichsoperatoren
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.
Lassen Sie uns die Größe dieser Punkte vom Ursprung vergleichen und das Ergebnis zu diesem Zweck zurückgeben. 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)
Ausgabe
True False False
Ebenso sind die speziellen Funktionen, die wir implementieren müssen, um andere Vergleichsoperatoren zu überladen, unten tabellarisch aufgeführt.
Operator | Ausdruck | Intern |
---|---|---|
Kleiner als | p1 < p2 | p1.__lt__(p2) |
Kleiner als oder gleich | p1 <= p2 | p1.__le__(p2) |
Gleich | p1 == p2 | p1.__eq__(p2) |
Ungleich | p1 != p2 | p1.__ne__(p2) |
Größer als | p1 > p2 | p1.__gt__(p2) |
Größer als oder gleich | p1 >= p2 | p1.__ge__(p2) |
Python