Python-operatør Overbelastning

Du kan endre betydningen av en operatør i Python, avhengig av operandene som brukes. I denne opplæringen lærer du hvordan du bruker operatøroverbelastning i Python Object Oriented Programming.

Python-operatør Overbelastning

Python-operatører jobber for innebygde klasser. Men den samme operatøren oppfører seg annerledes med forskjellige typer. For eksempel vil +operatøren utføre aritmetisk tillegg på to tall, slå sammen to lister eller sammenkoble to strenger.

Denne funksjonen i Python som lar den samme operatøren ha annen betydning i henhold til konteksten kalles operatøroverbelastning.

Så hva skjer når vi bruker dem med objekter i en brukerdefinert klasse? La oss se på følgende klasse, som prøver å 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)

Produksjon

 Sporing (siste anrop sist): Fil "", linje 9, på trykk (p1 + p2) TypeError: ikke støttet operand type (r) for +: 'Point' og 'Point'

Her kan vi se at a TypeErrorble reist, siden Python ikke visste hvordan man skulle legge to Pointobjekter sammen.

Imidlertid kan vi oppnå denne oppgaven i Python gjennom overbelastning av operatøren. Men først, la oss få en forestilling om spesialfunksjoner.

Python spesialfunksjoner

Klassefunksjoner som begynner med dobbelt understreking __kalles spesialfunksjoner i Python.

Disse funksjonene er ikke de typiske funksjonene vi definerer for en klasse. Den __init__()funksjonen vi definert ovenfor er en av dem. Det blir kalt hver gang vi lager et nytt objekt i den klassen.

Det er mange andre spesielle funksjoner i Python. Besøk Python Special Functions for å lære mer om dem.

Ved hjelp av spesialfunksjoner kan vi gjøre klassen vår kompatibel med innebygde funksjoner.

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

Anta at vi vil at print()funksjonen skal skrive ut koordinatene til Pointobjektet i stedet for det vi fikk. Vi kan definere en __str__()metode i klassen vår som styrer hvordan objektet blir skrevet ut. La oss se på hvordan vi kan oppnå 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)

La oss nå prøve print()funksjonen igjen.

 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)

Produksjon

 (2, 3)

Det er bedre. Det viser seg at denne samme metoden påkalles når vi bruker den innebygde funksjonen str()eller format().

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

Så når du bruker str(p1)eller format(p1), kaller Python p1.__str__()metoden internt . Derav navnet, spesielle funksjoner.

La oss nå gå tilbake til operatøroverbelastning.

Overbelastning av + operatøren

For å overbelaste +operatøren, må vi implementere __add__()funksjonen i klassen. Med stor makt kommer stort ansvar. Vi kan gjøre hva vi vil, inne i denne funksjonen. Men det er mer fornuftig å returnere et Pointobjekt av 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)

La oss nå prøve tilleggsoperasjonen igjen:

 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)

Produksjon

 (3,5)

Det som faktisk skjer er at når du bruker p1 + p2, ringer Python p1.__add__(p2)som igjen er det Point.__add__(p1,p2). Etter dette utføres tilsetningsoperasjonen slik vi spesifiserte.

På samme måte kan vi også overbelaste andre operatører. Den spesielle funksjonen som vi trenger å implementere, er tabellert nedenfor.

Operatør Uttrykk Internt
Addisjon p1 + p2 p1.__add__(p2)
Subtraksjon p1 - p2 p1.__sub__(p2)
Multiplikasjon p1 * p2 p1.__mul__(p2)
Makt p1 ** p2 p1.__pow__(p2)
Inndeling p1 / p2 p1.__truediv__(p2)
Etasjedivisjon p1 // p2 p1.__floordiv__(p2)
Resten (modulo) p1 % p2 p1.__mod__(p2)
Bitvis venstre skift p1 << p2 p1.__lshift__(p2)
Bitvis høyre 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 av sammenligningsoperatører

Python begrenser ikke operatørens overbelastning bare til aritmetiske operatører. Vi kan også overbelaste sammenligningsoperatører.

Anta at vi ønsket å implementere mindre enn symbol- <symbolet i Pointklassen vår .

La oss sammenligne størrelsen på disse punktene fra opprinnelsen og returnere resultatet for dette formålet. 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...