Du kan ändra innebörden av en operatör i Python beroende på vilka operander som används. I den här självstudien lär du dig hur man använder överbelastning av operatörer i Python Object Oriented Programming.
Python Operator Overloading
Python-operatörer arbetar för inbyggda klasser. Men samma operatör beter sig annorlunda med olika typer. Exempelvis kommer +
operatören att utföra aritmetisk addition på två siffror, slå samman två listor eller sammanfoga två strängar.
Denna funktion i Python som tillåter samma operatör att ha olika betydelse beroende på sammanhanget kallas operatörsöverbelastning.
Så vad händer när vi använder dem med objekt av en användardefinierad klass? Låt oss överväga följande klass, som försöker simulera en punkt i ett 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
Spårning (senaste samtalet senast): Fil "", rad 9, i tryck (p1 + p2) TypeError: operatyp (er) som inte stöds för +: 'Point' och 'Point'
Här kan vi se att a TypeError
höjdes, eftersom Python inte visste hur man skulle lägga till två Point
objekt tillsammans.
Vi kan dock uppnå denna uppgift i Python genom överbelastning av operatören. Men först, låt oss få en uppfattning om specialfunktioner.
Pythons specialfunktioner
Klassfunktioner som börjar med dubbel understrykning __
kallas specialfunktioner i Python.
Dessa funktioner är inte de typiska funktionerna som vi definierar för en klass. Den __init__()
funktion vi definierat ovan är en av dem. Det blir kallat varje gång vi skapar ett nytt objekt i den klassen.
Det finns många andra specialfunktioner i Python. Besök Pythons specialfunktioner för att lära dig mer om dem.
Med hjälp av specialfunktioner kan vi göra vår klass kompatibel med inbyggda funktioner.
>>> p1 = Point(2,3) >>> print(p1)
Antag att vi vill att print()
funktionen ska skriva ut Point
objektets koordinater istället för vad vi fick. Vi kan definiera en __str__()
metod i vår klass som styr hur objektet skrivs ut. Låt oss titta på hur vi kan uppnå detta:
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)
Låt oss nu prova 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 är bättre. Visas att samma metod åberopas när vi använder den inbyggda funktionen str()
eller format()
.
>>> str(p1) '(2,3)' >>> format(p1) '(2,3)'
Så när du använder str(p1)
eller format(p1)
kallar Python internt p1.__str__()
metoden. Därav namnet, specialfunktionerna.
Låt oss nu gå tillbaka till överbelastning av operatören.
Överbelastning av + operatören
För att överbelasta +
operatören måste vi implementera __add__()
funktionen i klassen. Med stor kraft kommer stort ansvar. Vi kan göra vad vi vill inom den här funktionen. Men det är mer förnuftigt att returnera ett Point
objekt av koordinatsumman.
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)
Låt oss nu prova tilläggsoperationen 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)
Vad som faktiskt händer är att när du använder p1 + p2
Python ringer p1.__add__(p2)
det i sin tur Point.__add__(p1,p2)
. Efter detta utförs tillsatsåtgärden som vi angav.
På samma sätt kan vi också överbelasta andra operatörer. Den speciella funktionen som vi behöver implementera visas i tabellen nedan.
Operatör | Uttryck | Internt |
---|---|---|
Tillägg | p1 + p2 | p1.__add__(p2) |
Subtraktion | p1 - p2 | p1.__sub__(p2) |
Multiplikation | p1 * p2 | p1.__mul__(p2) |
Kraft | p1 ** p2 | p1.__pow__(p2) |
Division | p1 / p2 | p1.__truediv__(p2) |
Golvdivision | p1 // p2 | p1.__floordiv__(p2) |
Resten (modulo) | p1 % p2 | p1.__mod__(p2) |
Bitvis vänster skift | p1 << p2 | p1.__lshift__(p2) |
Bitvis högerförskjutning | p1>> p2 | p1.__rshift__(p2) |
Bitvis OCH | p1 & p2 | p1.__and__(p2) |
Bitvis ELLER | p1 | p2 | p1.__or__(p2) |
Bitvis XOR | p1 p2 | p1.__xor__(p2) |
Bitvis INTE | ~p1 | p1.__invert__() |
Överbelastning av jämförelseoperatörer
Python begränsar inte operatörens överbelastning endast till aritmetiska operatörer. Vi kan också överbelasta jämförelseoperatörer.
Antag att vi ville implementera mindre än <
symbolen i vår Point
klass.
Låt oss jämföra storleken på dessa punkter från ursprunget och returnera resultatet för detta ändamål. Det kan implementeras enligt följande.
# 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)