Python Operator túlterhelés

Az operandusok függvényében megváltoztathatja az operátor jelentését a Pythonban. Ebben az oktatóanyagban megtudhatja, hogyan kell használni az operátorok túlterhelését a Python objektumorientált programozásban.

Python Operator túlterhelés

A Python operátorok beépített osztályoknál dolgoznak. De ugyanaz a kezelő másképp viselkedik a különböző típusokkal. Például az +operátor két számon elvégzi a számtani összeadást, két listát egyesít vagy két karakterláncot összefűz.

Ezt a szolgáltatást a Pythonban, amely lehetővé teszi, hogy ugyanazon operátor a kontextustól függően eltérő jelentéssel bírjon, operátor túlterhelésnek nevezzük.

Tehát mi történik, ha egy felhasználó által definiált osztály objektumaival használjuk őket? Vizsgáljuk meg a következő osztályt, amely megpróbál szimulálni egy pontot a 2-D koordinátarendszerben.

 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)

Kimenet

 Traceback (a legutóbbi hívás utoljára): "" fájl, 9. sor nyomtatásban (p1 + p2) TypeError: nem támogatott operandus típus (ok) a + -hoz: "Pont" és "Pont"

Itt láthatjuk, hogy a TypeErrorfelvetődött, mivel a Python nem tudta, hogyan adjon hozzá két Pointobjektumot.

Ezt a feladatot azonban elérhetjük a Pythonban az operátor túlterhelésével. De először vegyünk egy képet a speciális funkciókról.

Python speciális funkciók

A kettős aláhúzással kezdődő osztályfüggvényeket __speciális függvényeknek nevezzük a Pythonban.

Ezek a függvények nem azok a tipikus funkciók, amelyeket egy osztályhoz definiálunk. Az a __init__()funkció, amelyet fentebb definiáltunk, az egyik. Minden alkalommal hívják, amikor létrehozunk egy új objektumot az osztályból.

A Pythonban számos egyéb speciális funkció található. Látogassa meg a Python Special Functions funkciót, hogy többet tudjon meg róluk.

Speciális funkciókkal kompatibilisvé tehetjük osztályunkat a beépített funkciókkal.

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

Tegyük fel, hogy azt akarjuk, hogy a print()függvény kinyomtassa az Pointobjektum koordinátáit, nem pedig azt, amit kaptunk. Osztályunkban meghatározhatunk egy __str__()módszert, amely szabályozza az objektum nyomtatásának módját. Nézzük meg, hogyan érhetjük el ezt:

 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)

Most próbáljuk meg print()újra a funkciót.

 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)

Kimenet

 (2, 3)

Ez jobb. Kiderült, hogy ez ugyanaz a módszer akkor aktiválódik, ha használjuk a beépített függvény str()vagy format().

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

Tehát a str(p1)vagy használatakor a format(p1)Python belsőleg meghívja a p1.__str__()módszert. Innen a név, a speciális funkciók.

Térjünk vissza a kezelő túlterheléséhez.

A + kezelő túlterhelése

Az +operátor túlterheléséhez be kell vezetnünk a __add__()függvényt az osztályba. Nagy hatalommal jár a nagy felelősség. Bármit megtehetünk, ebben a funkcióban. De ésszerűbb Pointa koordinátaösszeg objektumát visszaadni .

 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)

Most próbáljuk meg újra az összeadási műveletet:

 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)

Kimenet

 (3,5)

What actually happens is that, when you use p1 + p2, Python calls p1.__add__(p2) which in turn is Point.__add__(p1,p2). After this, the addition operation is carried out the way we specified.

Similarly, we can overload other operators as well. The special function that we need to implement is tabulated below.

Operator Expression Internally
Addition p1 + p2 p1.__add__(p2)
Subtraction p1 - p2 p1.__sub__(p2)
Multiplication p1 * p2 p1.__mul__(p2)
Power p1 ** p2 p1.__pow__(p2)
Division p1 / p2 p1.__truediv__(p2)
Floor Division p1 // p2 p1.__floordiv__(p2)
Remainder (modulo) p1 % p2 p1.__mod__(p2)
Bitwise Left Shift p1 << p2 p1.__lshift__(p2)
Bitwise Right Shift p1>> p2 p1.__rshift__(p2)
Bitwise AND p1 & p2 p1.__and__(p2)
Bitwise OR p1 | p2 p1.__or__(p2)
Bitwise XOR p1 p2 p1.__xor__(p2)
Bitwise NOT ~p1 p1.__invert__()

Overloading Comparison Operators

Python does not limit operator overloading to arithmetic operators only. We can overload comparison operators as well.

Suppose we wanted to implement the less than symbol < symbol in our Point class.

Let us compare the magnitude of these points from the origin and return the result for this purpose. It can be implemented as follows.

 # 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)

érdekes cikkek...