Pythoni operaatori ülekoormus

Operaatori tähendust saate Pythonis muuta sõltuvalt kasutatavatest operandidest. Selles õpetuses saate teada, kuidas kasutada operaatori ülekoormamist Pythoni objektile orienteeritud programmeerimises.

Pythoni operaatori ülekoormus

Pythoni operaatorid töötavad sisseehitatud klassides. Kuid sama operaator käitub eri tüüpidega erinevalt. Näiteks teeb +operaator kahele numbrile aritmeetilise liitmise, ühendab kaks loendit või liidab kaks stringi.

Seda Pythoni funktsiooni, mis võimaldab samal operaatoril vastavalt kontekstile erinevat tähendust nimetada operaatori ülekoormuseks.

Mis siis juhtub, kui kasutame neid kasutaja määratud klassi objektidega? Vaatleme järgmist klassi, mis püüab simuleerida punkti 2-D koordinaatide süsteemis.

 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)

Väljund

 Traceback (viimane kõne viimati): fail "", rida 9, trükituna (p1 + p2) TypeError: +: 'Point' ja 'Point' ei toeta operanditüüpi (tüüpe)

Siin näeme, et TypeErrortõsteti a, kuna Python ei osanud kahte Pointobjekti kokku liita.

Kuid selle ülesande saame Pythonis saavutada operaatori ülekoormuse kaudu. Kuid kõigepealt võtame ettekujutuse erifunktsioonidest.

Pythoni erifunktsioonid

Topeltkriipsuga algavaid klassi funktsioone __nimetatakse Pythonis erifunktsioonideks.

Need funktsioonid pole tüüpilised funktsioonid, mille klassi jaoks määratleme. __init__()Funktsiooni me eespool määratletud on üks neist. Seda nimetatakse iga kord, kui loome selle klassi uue objekti.

Pythonis on arvukalt muid erifunktsioone. Nende kohta lisateabe saamiseks külastage Pythoni erifunktsioone.

Spetsiaalsete funktsioonide abil saame oma klassi ühildada sisseehitatud funktsioonidega.

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

Oletame, et soovime, et print()funktsioon prindiks saadud koordinaadid Pointobjekti asemel. Saame __str__()oma klassis määratleda meetodi, mis kontrollib objekti printimist. Vaatame, kuidas seda saavutada:

 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)

Nüüd proovime print()funktsiooni uuesti proovida .

 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)

Väljund

 (2, 3)

See on parem. Selgub, et seda sama meetodit kasutatakse siis, kui kasutame sisseehitatud funktsiooni str()või format().

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

Nii et kui kasutate str(p1)või format(p1), kutsub Python p1.__str__()meetodit sisemiselt . Siit ka nimi, erifunktsioonid.

Nüüd pöördume tagasi operaatori ülekoormuse juurde.

+ Operaatori ülekoormus

+Operaatori ülekoormamiseks peame __add__()klassis rakendama funktsiooni. Suure võimuga kaasneb suur vastutus. Selle funktsiooni sees võime teha kõike, mis meile meeldib. Kuid mõistlikum on tagastada Pointkoordinaatide summa objekt.

 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)

Proovime nüüd uuesti liitmistoimingut:

 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)

Väljund

 (3,5)

Tegelikult juhtub see, et kui kasutate p1 + p2, helistab Python, p1.__add__(p2)mis omakorda on Point.__add__(p1,p2). Pärast seda viiakse liitmistoiming läbi meie määratud viisil.

Samamoodi võime ka teisi operaatoreid üle koormata. Erifunktsioon, mille peame rakendama, on toodud allpool.

Operaator Väljendus Sisemiselt
Lisamine p1 + p2 p1.__add__(p2)
Lahutamine p1 - p2 p1.__sub__(p2)
Korrutamine p1 * p2 p1.__mul__(p2)
Võimsus p1 ** p2 p1.__pow__(p2)
Jaotus p1 / p2 p1.__truediv__(p2)
Põrandadivisjon p1 // p2 p1.__floordiv__(p2)
Ülejäänud (moodul) p1 % p2 p1.__mod__(p2)
Nuppude kaupa vasakpoolne nihe p1 << p2 p1.__lshift__(p2)
Parempoolne nihe paremale p1>> p2 p1.__rshift__(p2)
Pikkade kaupa JA p1 & p2 p1.__and__(p2)
Piki VÕI p1 | p2 p1.__or__(p2)
Piki XOR p1 p2 p1.__xor__(p2)
Bititi EI ~p1 p1.__invert__()

Võrdlusoperaatorite ülekoormamine

Python ei piira operaatori ülekoormamist ainult aritmeetikaoperaatoritega. Võime koormata ka võrdlusoperaatoreid.

Oletame, et tahtsime <oma Pointklassis rakendada sümbolist vähem kui sümbolit .

Võrdleme nende punktide suurust päritolust ja tagastame tulemuse sel eesmärgil. Seda saab rakendada järgmiselt.

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

Huvitavad Artiklid...