Overbelasting door Python-operator

U kunt de betekenis van een operator in Python wijzigen, afhankelijk van de gebruikte operanden. In deze tutorial leer je hoe je operatoroverbelasting gebruikt in Python Object Oriented Programming.

Overbelasting door Python-operator

Python-operators werken voor ingebouwde klassen. Maar dezelfde operator gedraagt ​​zich anders met verschillende typen. De +operator voert bijvoorbeeld rekenkundige optellingen uit op twee getallen, voegt twee lijsten samen of voegt twee strings samen.

Deze functie in Python waarmee dezelfde operator een verschillende betekenis kan hebben volgens de context, wordt operatoroverbelasting genoemd.

Dus wat gebeurt er als we ze gebruiken met objecten van een door de gebruiker gedefinieerde klasse? Laten we eens kijken naar de volgende klasse, die een punt in een 2D-coördinatensysteem probeert te simuleren.

 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)

Uitvoer

 Traceback (meest recente oproep laatste): Bestand "", regel 9, in print (p1 + p2) TypeError: niet-ondersteunde operand-type (s) voor +: 'Point' en 'Point'

Hier kunnen we zien dat a TypeErrorwerd verhoogd, aangezien Python niet wist hoe hij twee Pointobjecten bij elkaar moest optellen .

We kunnen deze taak echter in Python bereiken door overbelasting van de operator. Maar laten we eerst eens kijken naar speciale functies.

Python speciale functies

Klassefuncties die beginnen met een dubbel onderstrepingsteken, __worden in Python speciale functies genoemd.

Deze functies zijn niet de typische functies die we voor een klasse definiëren. De __init__()functie die we hierboven hebben gedefinieerd, is er een van. Het wordt elke keer dat we een nieuw object van die klasse maken, opgeroepen.

Er zijn tal van andere speciale functies in Python. Bezoek Python Special Functions om er meer over te leren.

Met behulp van speciale functies kunnen we onze klas compatibel maken met ingebouwde functies.

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

Stel dat we willen dat de print()functie de coördinaten van het Pointobject afdrukt in plaats van wat we hebben. We kunnen een __str__()methode in onze klasse definiëren die bepaalt hoe het object wordt afgedrukt. Laten we eens kijken hoe we dit kunnen bereiken:

 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)

Laten we nu de print()functie opnieuw proberen .

 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)

Uitvoer

 (2, 3)

Dat is beter. Blijkt dat dezelfde methode wordt aangeroepen wanneer we de ingebouwde functie str()of gebruiken format().

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

Dus als je str(p1)of gebruikt format(p1), roept Python intern de p1.__str__()methode aan. Vandaar de naam, speciale functies.

Laten we nu teruggaan naar de overbelasting van de operator.

Overbelasting van de + Operator

Om de +operator te overbelasten , moeten we de __add__()functie in de klas implementeren . Met grote kracht komt een grote verantwoordelijkheid. Binnen deze functie kunnen we doen wat we willen. Maar het is verstandiger om een Pointobject van de coördinatensom terug te geven.

 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)

Laten we nu de optelbewerking opnieuw proberen:

 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)

Uitvoer

 (3,5)

Wat er feitelijk gebeurt, is dat, wanneer u gebruikt p1 + p2, Python aanroept, p1.__add__(p2)wat op zijn beurt is Point.__add__(p1,p2). Hierna wordt de additiebewerking uitgevoerd zoals we hebben gespecificeerd.

Evenzo kunnen we ook andere operators overbelasten. De speciale functie die we moeten implementeren, wordt hieronder weergegeven.

Operator Uitdrukking Intern
Toevoeging p1 + p2 p1.__add__(p2)
Aftrekken p1 - p2 p1.__sub__(p2)
Vermenigvuldiging p1 * p2 p1.__mul__(p2)
Kracht p1 ** p2 p1.__pow__(p2)
Divisie p1 / p2 p1.__truediv__(p2)
Floor Divisie p1 // p2 p1.__floordiv__(p2)
Rest (modulo) p1 % p2 p1.__mod__(p2)
Bitsgewijs naar links verschuiven p1 << p2 p1.__lshift__(p2)
Bitwise Right Shift p1>> p2 p1.__rshift__(p2)
Bitwise EN p1 & p2 p1.__and__(p2)
Bitsgewijs OF p1 | p2 p1.__or__(p2)
Bitsgewijze XOR p1 p2 p1.__xor__(p2)
Bitsgewijs NIET ~p1 p1.__invert__()

Overbelastende vergelijkingsoperatoren

Python beperkt de overbelasting van operators niet tot alleen rekenkundige operators. We kunnen ook vergelijkingsoperatoren overbelasten.

Stel dat we het symbool voor minder dan <symbool in onze Pointklas willen implementeren .

Laten we de grootte van deze punten vanaf de oorsprong vergelijken en het resultaat voor dit doel retourneren. Het kan als volgt worden geïmplementeerd.

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