Python-operaattorin ylikuormitus

Voit muuttaa operaattorin merkitystä Pythonissa käytettyjen operandien mukaan. Tässä opetusohjelmassa opit käyttämään operaattorin ylikuormitusta Python Object Oriented Programming -ohjelmassa.

Python-operaattorin ylikuormitus

Python-operaattorit työskentelevät sisäänrakennetuissa luokissa. Mutta sama operaattori käyttäytyy eri tavalla eri tyyppien kanssa. Esimerkiksi +operaattori suorittaa aritmeettisen lisäyksen kahteen numeroon, yhdistää kaksi luetteloa tai yhdistää kaksi merkkijonoa.

Tätä Pythonin ominaisuutta, jonka avulla sama operaattori voi olla eri merkityksessä kontekstin mukaan, kutsutaan operaattorin ylikuormitukseksi.

Joten mitä tapahtuu, kun käytämme niitä käyttäjän määrittelemän luokan objektien kanssa? Tarkastellaan seuraavaa luokkaa, joka yrittää simuloida pistettä 2-D-koordinaattijärjestelmässä.

 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)

Tuotos

 Seuranta (viimeisin puhelu viimeisin): Tiedosto "", rivi 9, tulostettuna (p1 + p2) TypeError: ei-tuetut operandityypit tyypille +: 'Piste' ja 'Piste'

Täällä voimme nähdä, että a TypeErrornostettiin, koska Python ei tiennyt kuinka lisätä kahta Pointkohdetta yhteen.

Voimme kuitenkin saavuttaa tämän tehtävän Pythonissa operaattorin ylikuormituksen avulla. Mutta ensin otetaan käsitys erityistoiminnoista.

Python-erikoistoiminnot

Kaksoisviivalla alkavia luokan toimintoja __kutsutaan Pythonissa erikoistoiminnoiksi.

Nämä toiminnot eivät ole tyypillisiä funktioita, jotka määritämme luokalle. Edellä __init__()määritelty toiminto on yksi niistä. Sitä kutsutaan joka kerta, kun luomme uuden luokan objektin.

Pythonissa on lukuisia muita erikoistoimintoja. Vieraile Python-erikoistoiminnoissa saadaksesi lisätietoja niistä.

Erikoistoimintojen avulla voimme tehdä luokastamme yhteensopivan sisäänrakennettujen toimintojen kanssa.

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

Oletetaan, että haluamme, että print()funktio tulostaa Pointobjektin koordinaatit sen sijaan, että saimme. Voimme määritellä __str__()luokassamme menetelmän, joka ohjaa kohteen tulostusta. Katsotaanpa, miten voimme saavuttaa tämän:

 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)

Yritetään nyt print()toimintoa uudelleen.

 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)

Tuotos

 (2, 3)

Tuo on parempi. Osoittautuu, että tätä samaa menetelmää käytetään, kun käytämme sisäänrakennettua toimintoa str()tai format().

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

Joten, kun käytät str(p1)tai format(p1), Python kutsuu sisäisesti p1.__str__()menetelmää. Tästä syystä nimi, erikoistoiminnot.

Palataan nyt käyttäjän ylikuormitukseen.

+ Operaattorin ylikuormitus

+Operaattorin ylikuormittamiseksi meidän on toteutettava __add__()funktio luokassa. Suurella voimalla on suuri vastuu. Voimme tehdä mitä haluamme, tämän toiminnon sisällä. Mutta on järkevämpää palauttaa Pointkoordinaattien summa.

 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)

Yritetään nyt lisäystoimintoa uudelleen:

 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)

Tuotos

 (3,5)

Todellisuudessa tapahtuu, että kun käytät p1 + p2, Python soittaa, p1.__add__(p2)mikä puolestaan ​​on Point.__add__(p1,p2). Tämän jälkeen lisäysoperaatio suoritetaan määritellyllä tavalla.

Vastaavasti voimme ylikuormittaa myös muita operaattoreita. Erityinen toiminto, joka meidän on toteutettava, on esitetty alla.

Operaattori Ilmaisu Sisäisesti
Lisäys p1 + p2 p1.__add__(p2)
Vähennyslasku p1 - p2 p1.__sub__(p2)
Kertolasku p1 * p2 p1.__mul__(p2)
Teho p1 ** p2 p1.__pow__(p2)
Divisioona p1 / p2 p1.__truediv__(p2)
Kerrosjako p1 // p2 p1.__floordiv__(p2)
Loput (moduuli) p1 % p2 p1.__mod__(p2)
Bitti vasemmalle -vaihto p1 << p2 p1.__lshift__(p2)
Bittisuuntainen oikea vaihto p1>> p2 p1.__rshift__(p2)
Bittikohtaisesti JA p1 & p2 p1.__and__(p2)
Bittiä TAI p1 | p2 p1.__or__(p2)
Bitteittäin XOR p1 p2 p1.__xor__(p2)
Bittikohtaisesti EI ~p1 p1.__invert__()

Vertailuoperaattoreiden ylikuormitus

Python ei rajoita operaattorin ylikuormitusta vain aritmeettisiin operaattoreihin. Voimme myös ylikuormittaa vertailuoperaattoreita.

Oletetaan halusimme toteuttaa alle symboli <symboli meidän Pointluokassa.

Verrataanpa näiden pisteiden suuruutta alkuperästä ja palautetaan tulos tähän tarkoitukseen. Se voidaan toteuttaa seuraavasti.

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

Mielenkiintoisia artikkeleita...