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)