V rozsáhlém světě programování v Pythonu existuje řada funkcí, které si začátečníci často nevšimnou, přesto mají v ekosystému jazyka značný význam.
Magické metody jsou souborem před metoddefinite v Pythonu, které poskytují speciální syntaktické funkce. Jsou snadno rozpoznatelné podle jejich dvojitých čárek na začátku a na konci, jako __init__, __call__, __len__
… atd.
Magické metody umožňují uživatelským objektům chovat se podobně jako vestavěné typy Pythonu.
V tomto článku se zaměříme na výkonné funkce dunder. Prozkoumáme jejich účel a prodiskutujeme jejich použití.
Ať už jste začátečník v Pythonu nebo zkušený programátor, cílem tohoto článku je poskytnout vám komplexní pochopení funkcí Dunder, díky čemuž bude vaše kódování v Pythonu efektivnější a zábavnější.
Pamatujte, že kouzlo Pythonu nespočívá pouze v jeho jednoduchosti a všestrannosti, ale také v jeho výkonných funkcích, jako jsou funkce Dunder.
Možná nejzákladnější dunderova funkce ze všech. Toto je magická metoda, kterou Python automaticky volá, kdykoli vytvoříme (nebo jak název napovídá, inicializujeme) nový objekt.__init__
třída pizza:
def __init__(vlastní, velikost, polevy):
self.velikost = velikost
self.toppings = polevy
# Nyní vytvoříme pizzu
my_pizza = Pizza('velká', ['pepperoni', 'houby'])
print(my_pizza.size) # Toto vytiskne: velké
print(my_pizza.toppings) # Toto vytiskne: ['pepperoni', 'houby']
V tomto příkladu je vytvořena třída s názvem Pizza. Nastavili jsme naši funkci __init__ tak, aby zahrnovala parametry, které mají být specifikovány při inicializaci, a nastavili jsme je jako vlastnosti pro náš vlastní objekt.
Zde se používá k reprezentaci instance třídy. Když tedy napíšeme self.size = size, říkáme: „Hej, tento objekt pizzy má atribut size size
a chci, aby měl jakoukoli velikost, kterou jsem uvedl při vytváření objektu“.
Toto je magická metoda Pythonu, která nám to umožňuje definish popis pro naši zakázkovou položku.
Když tisknete objekt nebo jej převádíte na řetězec pomocí str()
, Python zkontrolujte, zda máte defiPřišel jsem na metodu __str__
pro třídu tohoto objektu.
Pokud ano, použijte tuto metodu k převodu objektu na řetězec.
Náš příklad Pizza můžeme rozšířit o funkci __str__
takto:
class Pizza: def __init__(self, size, polevy): self.size = size self.toppings = polevy def __str__(self): return f"A {self.size} pizza with {', '.join(self.toppings) )}" my_pizza = Pizza('large', ['pepperoni', 'houby']) print(my_pizza) # Vytiskne se: Velká pizza s feferonkami, houbami
__repr__
Funkce __str__ je spíše neformálním způsobem popisu vlastností objektu. Na druhou stranu se __repr__ používá k poskytnutí formálnějšího, podrobnějšího a jednoznačnějšího popisu vlastního objektu.
Pokud zavoláte repr()
na objektu nebo stačí zadat název objektu do konzoly, Python vyhledá metodu __repr__
.
Se __str__
Není definite, Python použije __repr__
jako zálohu při pokusu vytisknout objekt nebo jej převést na řetězec. Často je to tedy dobrý nápad defidokončit alespoň __repr__
, i když ne defivyjde __str__
.
Zde je návod, jak bychom mohli defiDokončit __repr__
pro náš příklad pizzy:
třída pizza:
def __init__(vlastní, velikost, polevy):
self.velikost = velikost
self.toppings = polevy
def __repr__(self):
return f"Pizza('{self.size}', {self.toppings})"
my_pizza = Pizza('velká', ['pepperoni', 'houby'])
print(repr(my_pizza)) # Toto vytiskne: Pizza('velka', ['pepperoni', 'houby'])
__repr__
vám dává řetězec, který můžete spustit jako příkaz Pythonu pro opětovné vytvoření objektu pizza, zatímco __str__
vám dává lidštější popis. Doufám, že vám to pomůže žvýkat tyto dunderovy metody trochu lépe!
V Pythonu všichni víme, že je možné sčítat čísla pomocí operátoru +
, Jako 3 + 5
.
Ale co když chceme přidat instance nějakého vlastního objektu?
Funkce dunder __add__
právě to nám umožňuje. Dává nám to schopnost defichování operátora +
na našich personalizovaných položkách.
V zájmu konzistence předpokládejme, že chceme defidokončit chování +
na našem příkladu pizzy. Řekněme, že kdykoli přidáme dvě nebo více pizz dohromady, automaticky se spojí všechny jejich polevy. Může to vypadat následovně:
třída pizza:
def __init__(vlastní, velikost, polevy):
self.velikost = velikost
self.toppings = polevy
def __add__(self, other):
pokud ne isinstance (jiné, Pizza):
raise TypeError("Můžete přidat pouze další pizzu!")
new_toppings = vlastní.toppings + other.toppings
vrátit pizzu(vlastní velikost, nové_toppingy)
# Vytvoříme dvě pizzy
pizza1 = Pizza('velká', ['pepperoni', 'houby'])
pizza2 = Pizza('velká', ['olivy', 'ananas'])
# A teď je „přidejme“.
combined_pizza = pizza1 + pizza2
print(combined_pizza.toppings) # Toto vytiskne: ['pepperoni', 'houby', 'olivy', 'ananas']
Podobně jako dunder __add__
, můžeme také defidokončit další aritmetické funkce jako např __sub__
(odčítáním pomocí operátoru -
) A __mul__
(pro násobení pomocí operátoru *
).
Tato Dunderova metoda nám to umožňuje defidokončit funkci len()
se musí vrátit pro naše přizpůsobené položky.
Používá Python len()
získat délku nebo velikost datové struktury, jako je seznam nebo řetězec.
V kontextu našeho příkladu bychom mohli říci, že „délka“ pizzy je počet náplní, které má. Zde je návod, jak bychom to mohli implementovat:
třída pizza:
def __init__(vlastní, velikost, polevy):
self.velikost = velikost
self.toppings = polevy
def __len__(self):
vratná čočka (samovolné polevy)
# Pojďme vytvořit pizzu
my_pizza = Pizza('velká', ['pepperoni', 'houby', 'olivy'])
print(len(my_pizza)) # Toto vytiskne: 3
V metodě __len__ vracíme pouze délku seznamu toppings
. Nyní, len(my_pizza)
řekne nám, kolik je na něm zálivek my_pizza
.
Tato dunderova metoda umožňuje objektům, aby byly iterovatelné, tj. mohou být použity ve smyčce for.
K tomu musíme také defidokončit funkci __next__
, Toto se používá pro definish chování, které by mělo vrátit další hodnotu v iteraci. Mělo by to také signalizovat iterovatelné v případě, že v sekvenci nejsou žádné další prvky. Obvykle toho dosáhneme vyvoláním výjimky StopIteration
.
Pro náš příklad pizzy řekněme, že chceme iterovat polevy. Mohli bychom udělat naši třídu pizzy iterovatelnou definendo metoda __iter__
:
třída pizza:
def __init__(vlastní, velikost, polevy):
self.velikost = velikost
self.toppings = polevy
def __iter__(self):
self.n = 0
vrátit sebe
def __next__(self):
if self.n < len(self.toppings):
výsledek = self.toppings[self.n]
self.n += 1
vrátit výsledek
jiný:
zvýšit StopIteration
# Pojďme vytvořit pizzu
my_pizza = Pizza('velká', ['pepperoni', 'houby', 'olivy'])
# A teď si to zopakujeme
pro zálivku v my_pizza:
potisk (poleva)
V tomto případě volá smyčka for __iter__
, který inicializuje čítač (self.n)
a vrátí samotný objekt pizzy (self)
.
Poté zavolá smyčka for __next__
získat každou zálivku v pořadí.
Kdy __next__
vrátila všechna koření, StopIteration
vyvolá výjimku a smyčka for nyní ví, že již neexistují žádné přelivy, a tak přeruší proces iterace.
Ercole Palmeri
Námořní sektor je skutečnou globální ekonomickou velmocí, která se dostala na 150miliardový trh...
Minulé pondělí Financial Times oznámily dohodu s OpenAI. FT licencuje svou prvotřídní žurnalistiku…
Miliony lidí platí za streamovací služby a platí měsíční předplatné. Je obecný názor, že jste…
Společnost Coveware od společnosti Veeam bude i nadále poskytovat služby reakce na incidenty v oblasti kybernetického vydírání. Coveware nabídne forenzní a sanační schopnosti…