Python Operator Overloading

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 TypeErrorhöjdes, eftersom Python inte visste hur man skulle lägga till två Pointobjekt 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 Pointobjektets 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 Pointobjekt 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 + p2Python 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 Pointklass.

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)

Intressanta artiklar...