Python Operator Overbelastning

Du kan ændre betydningen af ​​en operator i Python afhængigt af de anvendte operander. I denne vejledning lærer du, hvordan du bruger overbelastning af operatører i Python Object Oriented Programming.

Python Operator Overbelastning

Python-operatører arbejder for indbyggede klasser. Men den samme operatør opfører sig forskelligt med forskellige typer. For eksempel vil +operatøren udføre aritmetisk tilføjelse på to tal, flette to lister eller sammenkæde to strenge.

Denne funktion i Python, der gør det muligt for den samme operatør at have forskellig betydning i henhold til konteksten kaldes operatøroverbelastning.

Så hvad sker der, når vi bruger dem med objekter i en brugerdefineret klasse? Lad os overveje følgende klasse, der forsøger at simulere et punkt i 2-D koordinatsystem.

 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)

Produktion

 Traceback (seneste opkald sidst): Fil "", linje 9, i tryk (p1 + p2) TypeError: ikke-understøttet operand-type (r) for +: 'Point' og 'Point'

Her kan vi se, at a TypeErrorblev rejst, da Python ikke vidste, hvordan man tilføjede to Pointobjekter sammen.

Vi kan dog opnå denne opgave i Python gennem operatøroverbelastning. Men lad os først få et indtryk af specielle funktioner.

Python-specialfunktioner

Klassefunktioner, der begynder med dobbelt understregning __, kaldes specielle funktioner i Python.

Disse funktioner er ikke de typiske funktioner, som vi definerer for en klasse. Den __init__()funktion vi defineret ovenfor er en af dem. Det kaldes hver gang vi opretter et nyt objekt i den klasse.

Der er mange andre specielle funktioner i Python. Besøg Python Special Funktioner for at lære mere om dem.

Ved hjælp af specielle funktioner kan vi gøre vores klasse kompatibel med indbyggede funktioner.

 >>> p1 = Point(2,3) >>> print(p1) 

Antag, at vi vil have print()funktionen til at udskrive Pointobjektets koordinater i stedet for det, vi fik. Vi kan definere en __str__()metode i vores klasse, der styrer, hvordan objektet bliver udskrevet. Lad os se på, hvordan vi kan opnå dette:

 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)

Lad os nu prøve print()funktionen igen.

 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)

Produktion

 (2, 3)

Det er bedre. Det viser sig, at den samme metode påberåbes, når vi bruger den indbyggede funktion str()eller format().

 >>> str(p1) '(2,3)' >>> format(p1) '(2,3)'

Så når du bruger str(p1)eller format(p1), kalder Python internt p1.__str__()metoden. Deraf navnet, specielle funktioner.

Lad os nu gå tilbage til operatøroverbelastning.

Overbelastning af + operatøren

For at overbelaste +operatøren skal vi implementere __add__()funktionen i klassen. Med store magtbeføjelser følger store forpligtigelser. Vi kan gøre hvad vi vil inden i denne funktion. Men det er mere fornuftigt at returnere et Pointobjekt af koordinatsummen.

 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)

Lad os nu prøve tilføjelsesoperationen igen:

 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)

Produktion

 (3,5)

Hvad der faktisk sker er, at når du bruger p1 + p2, kalder Python, p1.__add__(p2)hvilket igen er Point.__add__(p1,p2). Efter dette udføres tilføjelsesoperationen som vi specificerede.

På samme måde kan vi også overbelaste andre operatører. Den særlige funktion, som vi har brug for at implementere, er vist i nedenstående tabel.

Operatør Udtryk Internt
Tilføjelse p1 + p2 p1.__add__(p2)
Subtraktion p1 - p2 p1.__sub__(p2)
Multiplikation p1 * p2 p1.__mul__(p2)
Strøm p1 ** p2 p1.__pow__(p2)
Division p1 / p2 p1.__truediv__(p2)
Floor Division p1 // p2 p1.__floordiv__(p2)
Resten (modulo) p1 % p2 p1.__mod__(p2)
Bitvis venstre skift p1 << p2 p1.__lshift__(p2)
Bitvis højre skift p1>> p2 p1.__rshift__(p2)
Bitvis OG p1 & p2 p1.__and__(p2)
Bitvis ELLER p1 | p2 p1.__or__(p2)
Bitvis XOR p1 p2 p1.__xor__(p2)
Bitvis IKKE ~p1 p1.__invert__()

Overbelastning af sammenligningsoperatører

Python begrænser ikke overbelastning af operatører til kun aritmetiske operatører. Vi kan også overbelaste sammenligningsoperatører.

Antag, at vi ville implementere mindre end <symbolsymbolet i vores Pointklasse.

Lad os sammenligne størrelsen af ​​disse punkter fra oprindelsen og returnere resultatet til dette formål. Det kan implementeres som følger.

 # 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 artikler...