Didžiuliame Python programavimo pasaulyje yra daugybė funkcijų, kurių pradedantieji dažnai nepastebi, tačiau turi didelę reikšmę kalbos ekosistemoje.
Magiški metodai yra išankstinių metodų rinkinysdefinites Python, kurios suteikia specialių sintaksinių savybių. Juos lengva atpažinti iš dvigubų brūkšnelių pradžioje ir pabaigoje, pvz __init__, __call__, __len__
… ir tt
Magiški metodai leidžia pasirinktiems objektams veikti panašiai kaip įtaisytieji Python tipai.
Šiame straipsnyje mes sutelksime dėmesį į galingas „dunder“ funkcijas. Išnagrinėsime jų paskirtį ir aptarsime jų naudojimą.
Nesvarbu, ar esate „Python“ naujokas, ar patyręs programuotojas, šio straipsnio tikslas – visapusiškai suprasti „Dunder“ funkcijas, todėl „Python“ kodavimo patirtis tampa veiksmingesnė ir malonesnė.
Atminkite, kad Python magija slypi ne tik paprastume ir universalumu, bet ir galingose funkcijose, tokiose kaip Dunder funkcijos.
Galbūt pati paprasčiausia dunder funkcija. Tai magiškas metodas, kurį Python automatiškai iškviečia, kai sukuriame (arba, kaip rodo pavadinimas, inicijuojame) naują objektą.__init__
klasės pica:
def __init__(savaime, dydis, priedai):
pats.dydis = dydis
savaime.užpilai = priedai
# Dabar sukurkime picą
mano_pica = Pica ("didelė", ["pipirai", "grybai"])
print(mano_pica.dydis) # Bus spausdinama: didelis
print(my_pica.toppings) # Bus išspausdinta: ['pepperoni', 'grybai']
Šiame pavyzdyje sukuriama klasė pavadinimu Pica. Mes nustatome savo funkciją __init__, kad įtrauktume parametrus, kuriuos reikia nurodyti inicijavimo metu, ir nustatome juos kaip savo pasirinktinio objekto ypatybes.
Čia jis naudojamas klasės egzemplioriui atstovauti. Taigi, kai rašome self.size = dydis, sakome: „Ei, šis picos objektas turi atributo dydį size
, ir noriu, kad jis būtų tokio dydžio, kokį nurodžiau kurdamas objektą“.
Tai yra Python magiškas metodas, leidžiantis mums tai padaryti defipateikite mūsų pasirinktinės prekės aprašymą.
Kai spausdinate objektą arba konvertuojate jį į eilutę naudodami str()
, Python patikrinkite, ar turite defiAš sugalvojau metodą __str__
to objekto klasei.
Jei taip, naudokite šį metodą, norėdami konvertuoti objektą į eilutę.
Galime išplėsti savo picos pavyzdį įtraukdami funkciją __str__
taip:
klasė Pica: def __init__(savarankiškas, dydis, priedai): self.size = dydis self.toppings = priedai def __str__(self): return f"A {self.size} pica su {', '.join(self.toppings) )}" my_pica = Pica('didelis', ['pipirai', 'grybai']) print(mano_pica) # Bus spausdinama: Didelė pica su pipirais, grybais
__repr__
Funkcija __str__ yra labiau neformalus būdas apibūdinti objekto savybes. Kita vertus, __repr__ naudojamas formalesniam, išsamesniam ir nedviprasmiškesniam pasirinkto objekto aprašymui.
Jei paskambinsi repr()
ant objekto arba tiesiog įvedate objekto pavadinimą į konsolę, Python ieškos metodo __repr__
.
Se __str__
tai nėra definite, naudos Python __repr__
kaip atsarginę kopiją bandant atspausdinti objektą arba konvertuoti jį į eilutę. Taigi dažnai tai yra gera idėja defibent jau baigti __repr__
, net jei to nedarote defiišeina __str__
.
Štai kaip galėtume defibaigti __repr__
mūsų picos pavyzdys:
klasės pica:
def __init__(savaime, dydis, priedai):
pats.dydis = dydis
savaime.užpilai = priedai
def __repr__(self):
grąžinti f"Pica('{self.size}', {self.toppings})"
mano_pica = Pica ("didelė", ["pipirai", "grybai"])
print(repr(mano_pica)) # Bus spausdinama: Pica('didelis', ['pipirai', 'grybai'])
__repr__
suteikia jums eilutę, kurią galite paleisti kaip Python komandą, kad atkurtumėte picos objektą, tuo tarpu __str__
pateikia žmogiškesnį aprašymą. Tikiuosi, kad tai padės jums šiek tiek geriau sukramtyti šiuos dunder metodus!
„Python“ programoje visi žinome, kad skaičių galima pridėti naudojant operatorių +
, Kaip 3 + 5
.
Bet ką daryti, jei norime pridėti kokio nors pasirinktinio objekto egzempliorių?
Dunder funkcija __add__
tai leidžia mums tai padaryti. Tai suteikia mums galimybę defistebėti operatoriaus elgesį +
mūsų suasmenintuose daiktuose.
Siekdami nuoseklumo, tarkime, kad to norime defiužbaigti elgesį +
mūsų picos pavyzdyje. Tarkime, kai dedame dvi ar daugiau picų, automatiškai bus sujungti visi jų priedai. Štai kaip tai gali atrodyti:
klasės pica:
def __init__(savaime, dydis, priedai):
pats.dydis = dydis
savaime.užpilai = priedai
def __add__(savęs, kitas):
jei ne atvejis (kita, pica):
raise TypeError ("Galite įdėti tik kitą picą!")
nauji_užpildai = savaime.užpildai + kiti.užpildai
grąžinti picą (savarankiškas dydis, nauji_užpildai)
# Sukurkime dvi picas
pica1 = pica ("didelė", ["pipirai", "grybai"])
pica2 = pica ("didelė", ["alyvuogės", "ananasas"])
# O dabar „pridėkime“ juos
kombinuota_pica = pica1 + pica2
print(combined_pica.toppings) # Bus spausdinama: ['pipirai', 'grybai', 'alyvuogės', 'ananasai']
Panašiai kaip dunder __add__
, mes taip pat galime defiužbaigti kitas aritmetines funkcijas, pvz __sub__
(atimant naudojant operatorių -
) Ir __mul__
(daugybai naudojant operatorių *
).
Šis dunder metodas mums leidžia defibaigti kokia funkcija len()
privalo grąžinti mūsų pritaikytas prekes.
Python naudoja len()
Norėdami gauti duomenų struktūros, pvz., sąrašo ar eilutės, ilgį arba dydį.
Mūsų pavyzdžio kontekste galėtume pasakyti, kad picos „ilgis“ yra joje esančių priedų skaičius. Štai kaip galėtume tai įgyvendinti:
klasės pica:
def __init__(savaime, dydis, priedai):
pats.dydis = dydis
savaime.užpilai = priedai
def __len__(pats):
grąžinti objektyvą (savaiminiai. priedai)
# Sukurkime picą
my_pizza = Pica ("didelė", ["pipirai", "grybai", "alyvuogės"])
print(len(mano_pica)) # Tai išspausdins: 3
__len__ metodu grąžiname tik sąrašo ilgį toppings
. Dabar, len(my_pizza)
jis parodys, kiek priedų yra ant jo my_pizza
.
Šis „dunder“ metodas leidžia objektus kartoti, t. y. jį galima naudoti „for“ cikle.
Norėdami tai padaryti, mes taip pat turime defiužbaigti funkciją __next__
, Tai naudojama definustatyti elgesį, kuris turėtų grąžinti kitą iteracijos reikšmę. Tai taip pat turėtų signalizuoti apie kartojimą, jei sekoje nebėra elementų. Paprastai tai pasiekiame taikydami išimtį StopIteration
.
Tarkime, kad picos pavyzdyje norime kartoti priedus. Galėtume padaryti savo picos klasę kartojamą definendo metodą __iter__
:
klasės pica:
def __init__(savaime, dydis, priedai):
pats.dydis = dydis
savaime.užpilai = priedai
def __iter__(self):
savarankiškai.n = 0
grąžinti save
def __next__(self):
if self.n < len(self.toppings):
rezultatas = self.toppings[self.n]
savarankiškai.n += 1
grąžinti rezultatą
Kitas:
pakelti StopIteration
# Sukurkime picą
my_pizza = Pica ("didelė", ["pipirai", "grybai", "alyvuogės"])
# O dabar pakartokime tai
mano_picos užpilui:
spausdinti (užpildymas)
Šiuo atveju skambina for kilpa __iter__
, kuris inicijuoja skaitiklį (self.n)
ir grąžina patį picos objektą (self)
.
Tada skambina for kilpa __next__
kad kiekvienas užpilas gautųsi paeiliui.
Kai __next__
grąžino visus prieskonius, StopIteration
ji daro išimtį ir for ciklas dabar žino, kad nebėra papildymų, todėl kartojimo procesas bus nutrauktas.
Ercole Palmeri
Lavindami smulkiosios motorikos įgūdžius dažydami, vaikai paruošiami sudėtingesniems įgūdžiams, pavyzdžiui, rašymui. Norėdami nuspalvinti…
Karinio jūrų laivyno sektorius yra tikra pasaulinė ekonominė galia, kuri pasiekė 150 mlrd.
Praėjusį pirmadienį „Financial Times“ paskelbė apie susitarimą su „OpenAI“. FT licencijuoja savo pasaulinio lygio žurnalistiką…
Milijonai žmonių moka už srautinio perdavimo paslaugas, mokėdami mėnesinius abonentinius mokesčius. Paplitusi nuomonė, kad jūs…