V obrovskom svete programovania Python existuje súbor funkcií, ktoré si začiatočníci často nevšimnú, no napriek tomu majú v ekosystéme jazyka značný význam.
Magické metódy sú súborom predmetóddefinite v Pythone, ktoré poskytujú špeciálne syntaktické funkcie. Ľahko ich spoznáte podľa dvojitých pomlčiek na začiatku a na konci, napr __init__, __call__, __len__
… atď.
Magické metódy umožňujú vlastným objektom správať sa podobne ako vstavané typy Pythonu.
V tomto článku sa zameriame na výkonné funkcie dunder. Preskúmame ich účel a prediskutujeme ich použitie.
Či už ste nováčik v Pythone alebo skúsený programátor, cieľom tohto článku je poskytnúť vám komplexné pochopenie funkcií Dunder, vďaka čomu bude vaša skúsenosť s kódovaním v Pythone efektívnejšia a príjemnejšia.
Pamätajte, že kúzlo Pythonu nespočíva len v jeho jednoduchosti a všestrannosti, ale aj v jeho výkonných funkciách, ako sú funkcie Dunder.
Možno najzákladnejšia dunderova funkcia zo všetkých. Toto je magická metóda, ktorú Python automaticky volá vždy, keď vytvoríme (alebo ako názov napovedá, inicializujeme) nový objekt.__init__
trieda pizza:
def __init__(vlastné, veľkosť, polevy):
self.veľkosť = veľkosť
self.toppings = polevy
# Teraz poďme vytvoriť pizzu
my_pizza = Pizza('veľká', ['pepperoni', 'huby'])
print(my_pizza.size) # Toto vytlačí: veľké
print(my_pizza.toppings) # Toto vytlačí: ['pepperoni', 'huby']
V tomto príklade je vytvorená trieda s názvom Pizza. Nastavili sme našu funkciu __init__ tak, aby zahŕňala parametre, ktoré sa majú zadať pri inicializácii, a nastavili sme ich ako vlastnosti pre náš vlastný objekt.
Tu sa používa na reprezentáciu inštancie triedy. Takže keď napíšeme self.size = size, hovoríme: „Hej, tento objekt pizze má atribút veľkosť size
a chcem, aby mal akúkoľvek veľkosť, ktorú som poskytol pri vytváraní objektu“.
Toto je magická metóda Pythonu, ktorá nám to umožňuje definish popis pre našu vlastnú položku.
Keď vytlačíte objekt alebo ho prevediete na reťazec pomocou str()
, Python skontrolujte, či máte defiPrišiel som na metódu __str__
pre triedu tohto objektu.
Ak áno, použite túto metódu na konverziu objektu na reťazec.
Náš príklad Pizza môžeme rozšíriť o funkciu __str__
nasledovne:
class Pizza: def __init__(vlastná, veľkosť, polevy): self.size = veľkosť self.toppings = polevy def __str__(self): return f"A {self.size} pizza with {', '.join(self.toppings) )}" moja_pizza = Pizza('large', ['pepperoni', 'huby']) print(my_pizza) # Vytlačí sa: Veľká pizza s feferónkami, hubami
__repr__
Funkcia __str__ je skôr neformálny spôsob popisu vlastností objektu. Na druhej strane, __repr__ sa používa na poskytnutie formálnejšieho, podrobnejšieho a jednoznačnejšieho popisu vlastného objektu.
Ak zavoláte repr()
na objekte alebo jednoducho napíšete názov objektu do konzoly, Python vyhľadá metódu __repr__
.
Se __str__
to nieje definite, Python použije __repr__
ako zálohu pri pokuse o tlač objektu alebo jeho konverziu na reťazec. Často je to teda dobrý nápad defidokončiť aspoň __repr__
, aj keď nie defivyjde __str__
.
Tu je návod, ako by sme mohli defiskončiť __repr__
pre náš príklad pizze:
trieda pizza:
def __init__(vlastné, veľkosť, polevy):
self.veľkosť = veľkosť
self.toppings = polevy
def __repr__(self):
return f"Pizza('{self.size}', {self.toppings})"
my_pizza = Pizza('veľká', ['pepperoni', 'huby'])
print(repr(my_pizza)) # Toto vytlačí: Pizza('veľká', ['pepperoni', 'huby'])
__repr__
vám dáva reťazec, ktorý môžete spustiť ako príkaz Pythonu na opätovné vytvorenie objektu pizza, zatiaľ čo __str__
dáva vám ľudskejší popis. Dúfam, že vám to pomôže lepšie žuť tieto dunderove metódy!
V Pythone všetci vieme, že je možné sčítať čísla pomocou operátora +
, Ako 3 + 5
.
Čo ak však chceme pridať inštancie nejakého vlastného objektu?
Dunderova funkcia __add__
práve to nám umožňuje. Dáva nám to schopnosť defisprávanie operátora +
na našich personalizovaných položkách.
V záujme konzistentnosti predpokladajme, že chceme defidokončiť správanie +
na našom príklade pizze. Povedzme, že kedykoľvek pridáme dve alebo viac pízz dohromady, automaticky sa spoja všetky ich polevy. Môže to vyzerať takto:
trieda pizza:
def __init__(vlastné, veľkosť, polevy):
self.veľkosť = veľkosť
self.toppings = polevy
def __add__(ja, iné):
ak nie je inštancia (iné, pizza):
raise TypeError("Môžete pridať iba ďalšiu pizzu!")
new_toppings = self.toppings + other.toppings
vrátiť pizzu (vlastná veľkosť, nové_polevy)
# Vytvoríme dve pizze
pizza1 = Pizza('veľká', ['pepperoni', 'huby'])
pizza2 = Pizza('veľká', ['olivy', 'ananás'])
# A teraz ich „pridajme“.
combined_pizza = pizza1 + pizza2
print(combined_pizza.toppings) # Toto vytlačí: ['pepperoni', 'huby', 'olivy', 'ananás']
Podobne ako dunder __add__
, môžeme tiež defidokončiť ďalšie aritmetické funkcie ako napr __sub__
(odčítaním pomocou operátora -
) A __mul__
(pre násobenie pomocou operátora *
).
Táto Dunderova metóda nám to umožňuje defidokončiť akú funkciu len()
musíme vrátiť pre naše prispôsobené položky.
Používa Python len()
získať dĺžku alebo veľkosť dátovej štruktúry, ako je zoznam alebo reťazec.
V kontexte nášho príkladu by sme mohli povedať, že „dĺžka“ pizze je počet zálievok, ktoré má. Takto by sme to mohli implementovať:
trieda pizza:
def __init__(vlastné, veľkosť, polevy):
self.veľkosť = veľkosť
self.toppings = polevy
def __len__(self):
vratná šošovka (samotné polevy)
# Poďme vytvoriť pizzu
my_pizza = Pizza('veľká', ['pepperoni', 'huby', 'olivy'])
print(len(my_pizza)) # Toto vytlačí: 3
V metóde __len__ vraciame iba dĺžku zoznamu toppings
. Teraz, len(my_pizza)
nám povie, koľko polevy je na ňom my_pizza
.
Táto dunderova metóda umožňuje objektom, aby boli iterovateľné, t.j. môžu byť použité v slučke for.
Aby sme to urobili, musíme tiež defidokončite funkciu __next__
, Používa sa na definish správanie, ktoré by malo vrátiť ďalšiu hodnotu v iterácii. Malo by to tiež signalizovať iterovateľné v prípade, že v sekvencii nie sú žiadne ďalšie prvky. Zvyčajne to dosiahneme vyvolaním výnimky StopIteration
.
Pre náš príklad pizze povedzme, že chceme zopakovať polevy. Mohli by sme urobiť našu triedu pizze iterovateľnou definendo metóda __iter__
:
trieda pizza:
def __init__(vlastné, veľkosť, polevy):
self.veľkosť = veľkosť
self.toppings = polevy
def __iter__(self):
self.n = 0
vrátiť seba
def __next__(self):
if self.n < len(self.toppings):
výsledok = vlastné polevy[self.n]
self.n += 1
vrátiť výsledok
inak:
zvýšiť StopIteration
# Poďme vytvoriť pizzu
my_pizza = Pizza('veľká', ['pepperoni', 'huby', 'olivy'])
# A teraz si to zopakujme
na polevu v my_pizza:
potlač (poleva)
V tomto prípade volá slučka for __iter__
, ktorý inicializuje počítadlo (self.n)
a vráti samotný predmet pizze (self)
.
Potom zavolá slučka for __next__
aby ste postupne dostali každú polevu.
keď __next__
vrátil všetky koreniny, StopIteration
vyvolá výnimku a cyklus for teraz vie, že už nie sú žiadne zálievky, a tak preruší proces iterácie.
Ercole Palmeri
Námorný sektor je skutočnou globálnou ekonomickou veľmocou, ktorá smerovala k 150 miliardovému trhu...
Minulý pondelok Financial Times oznámili dohodu s OpenAI. FT licencuje svoju žurnalistiku svetovej triedy…
Milióny ľudí platia za streamovacie služby a platia mesačné predplatné. Je bežný názor, že si…
Coveware od Veeam bude aj naďalej poskytovať služby reakcie na incidenty v oblasti kybernetického vydierania. Coveware ponúkne forenzné a sanačné schopnosti…