Operatoriaus reikšmę „Python“ galite pakeisti priklausomai nuo naudojamų operandų. Šioje pamokoje sužinosite, kaip naudotis operatoriaus perkrova programuojant „Python“ į objektus.
„Python“ operatoriaus perkrova
„Python“ operatoriai dirba įmontuotose klasėse. Bet tas pats operatorius su skirtingais tipais elgiasi skirtingai. Pvz., +
Operatorius atliks aritmetinį dviejų skaičių sujungimą, sujungs du sąrašus arba sujungs dvi eilutes.
Ši „Python“ funkcija, leidžianti tam pačiam operatoriui turėti skirtingą reikšmę pagal kontekstą, vadinama operatoriaus perkrova.
Taigi, kas atsitinka, kai juos naudojame su vartotojo apibrėžtos klasės objektais? Panagrinėkime šią klasę, kuri bando imituoti tašką 2-D koordinačių sistemoje.
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)
Rezultatas
Traceback (paskutinis paskutinis skambutis paskutinis): failas "", 9 eilutė, atspausdinta (p1 + p2) TypeError: nepalaikomi operandai (-ai), skirti +: 'Point' ir 'Point'
Čia galime pamatyti, kad TypeError
buvo iškeltas a, nes „Python“ nežinojo, kaip pridėti du Point
objektus.
Tačiau šią užduotį „Python“ galime pasiekti perkrovę operatorių. Tačiau pirmiausia įsivaizduokime apie specialias funkcijas.
„Python“ specialiosios funkcijos
Klasės funkcijos, kurios prasideda dvigubu pabraukimu __
, „Python“ vadinamos specialiosiomis funkcijomis.
Šios funkcijos nėra tipinės funkcijos, kurias mes apibrėžiame klasei. __init__()
Funkcija mes apibrėžta pirmiau yra vienas iš jų. Tai vadinama kiekvieną kartą, kai sukuriame naują tos klasės objektą.
„Python“ yra daugybė kitų specialiųjų funkcijų. Norėdami sužinoti daugiau apie jas, apsilankykite „Python“ specialiosiose funkcijose.
Naudodamiesi specialiomis funkcijomis, savo klasę galime suderinti su įmontuotomis funkcijomis.
>>> p1 = Point(2,3) >>> print(p1)
Tarkime, kad mes norime, kad print()
funkcija atspausdintų objekto koordinates, Point
o ne tai, ką gavome. Mes galime apibrėžti __str__()
savo klasės metodą, kuris kontroliuoja, kaip objektas spausdinamas. Pažvelkime, kaip tai pasiekti:
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)
Dabar pabandykime print()
funkciją dar kartą.
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)
Rezultatas
(2, 3)
Taip geriau. Pasirodo, kad tas pats metodas yra naudojamas, kai mes naudojame integruotą funkciją str()
arba format()
.
>>> str(p1) '(2,3)' >>> format(p1) '(2,3)'
Taigi, kai naudojate str(p1)
arba format(p1)
, „Python“ viduje iškviečia p1.__str__()
metodą. Iš čia kilo pavadinimas, specialiosios funkcijos.
Dabar grįžkime prie operatoriaus perkrovos.
„+“ Operatoriaus perkrova
Norėdami perkrauti +
operatorių, __add__()
klasėje turėsime įdiegti funkciją. Su didele galia ateina didelė atsakomybė. Mes galime daryti viską, kas mums patinka, šios funkcijos viduje. Bet protingiau grąžinti Point
koordinačių sumos 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)
Dabar pabandykime dar kartą atlikti papildymo operaciją:
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)
Rezultatas
(3,5)
Iš tikrųjų vyksta tai, kad kai naudojate p1 + p2
, „Python“ skambina p1.__add__(p2)
, o tai savo ruožtu yra Point.__add__(p1,p2)
. Po to papildymo operacija atliekama taip, kaip mes nurodėme.
Panašiai galime perkrauti ir kitus operatorius. Speciali funkcija, kurią turime įgyvendinti, pateikiama žemiau.
operatorius | Išraiška | Viduje |
---|---|---|
Papildymas | p1 + p2 | p1.__add__(p2) |
Atimtis | p1 - p2 | p1.__sub__(p2) |
Dauginimas | p1 * p2 | p1.__mul__(p2) |
Galia | p1 ** p2 | p1.__pow__(p2) |
Padalijimas | p1 / p2 | p1.__truediv__(p2) |
Aukštų skyrius | p1 // p2 | p1.__floordiv__(p2) |
Likutis (modulo) | p1 % p2 | p1.__mod__(p2) |
Kairysis kairysis poslinkis | p1 << p2 | p1.__lshift__(p2) |
Dešiniuoju poslinkiu į dešinę | p1>> p2 | p1.__rshift__(p2) |
Bitais IR | p1 & p2 | p1.__and__(p2) |
ARBA bitais | p1 | p2 | p1.__or__(p2) |
Bitais XOR | p1 p2 | p1.__xor__(p2) |
Bitiškai NE | ~p1 | p1.__invert__() |
Perkrovos palyginimo operatoriai
„Python“ neriboja operatoriaus perkrovos tik aritmetikos operatoriams. Mes taip pat galime perkrauti palyginimo operatorius.
Tarkime, kad <
savo Point
klasėje norėjome įdiegti simbolį, mažesnį už simbolį .
Palyginkime šių taškų dydį nuo kilmės ir grąžinkime rezultatą šiam tikslui. Tai galima įgyvendinti taip.
# 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)