I den stora världen av Python-programmering finns det en uppsättning funktioner som ofta går obemärkta förbi för nybörjare, men som ändå har stor betydelse för språkets ekosystem.
Magiska metoder är en uppsättning förmetoderdefinites i Python som ger speciella syntaktiska funktioner. De känns lätt igen på sina dubbla streck i början och slutet, typ __init__, __call__, __len__
… etc.
Magiska metoder tillåter anpassade objekt att bete sig liknande inbyggda Python-typer.
I den här artikeln kommer vi att fokusera på de kraftfulla dunderfunktionerna. Vi kommer att utforska deras syfte och diskutera deras användning.
Oavsett om du är en Python-nybörjare eller en erfaren programmerare, syftar den här artikeln till att ge dig en omfattande förståelse för Dunder-funktioner, vilket gör din Python-kodningsupplevelse mer effektiv och njutbar.
Kom ihåg att magin med Python inte bara ligger i dess enkelhet och mångsidighet, utan också i dess kraftfulla funktioner som Dunder-funktioner.
Kanske den mest grundläggande dunderfunktionen av alla. Detta är den magiska metoden som Python automatiskt anropar när vi skapar (eller som namnet antyder, initierar) ett nytt objekt.__init__
klass pizza:
def __init__(själv, storlek, toppings):
self.size = storlek
self.toppings = toppings
# Låt oss nu skapa en pizza
my_pizza = Pizza('stor', ['pepperoni', 'svamp'])
print(my_pizza.size) # Detta kommer att skriva ut: large
print(my_pizza.toppings) # Detta kommer att skriva ut: ['pepperoni', 'svampar']
I det här exemplet skapas en klass som heter Pizza. Vi ställer in vår __init__-funktion för att inkludera parametrarna som ska specificeras vid initialiseringstidpunkten och ställer in dem som egenskaper för vårt anpassade objekt.
Här används den för att representera klassens förekomst. Så när vi skriver self.size = size, säger vi, "Hej, det här pizzaobjektet har en attribut storlek size
, och jag vill att den ska ha vilken storlek jag än angav när jag skapade objektet”.
Detta är Pythons magiska metod som gör att vi kan definish en beskrivning för vår anpassade artikel.
När du skriver ut ett objekt eller konverterar det till en sträng med str()
, Python kolla om du har defiJag har kommit på en metod __str__
för det objektets klass.
Om så är fallet, använd den metoden för att konvertera objektet till en sträng.
Vi kan utöka vårt Pizza-exempel till att inkludera en funktion __str__
som följer:
klass Pizza: def __init__(själv, storlek, toppings): self.size = storlek self.toppings = toppings def __str__(self): returnera f"A {self.size} pizza med {', '.join(self.toppings )}" my_pizza = Pizza('large', ['pepperoni', 'svampar']) print(min_pizza) # Detta kommer att skriva ut: En stor pizza med pepperoni, svamp
__repr__
Funktionen __str__ är mer ett informellt sätt att beskriva egenskaperna hos ett objekt. Å andra sidan används __repr__ för att ge en mer formell, detaljerad och entydig beskrivning av det anpassade objektet.
Om du ringer repr()
på ett objekt eller så skriver du bara in objektnamnet i konsolen, kommer Python att leta efter en metod __repr__
.
Se __str__
det är det inte definite kommer Python att använda __repr__
som en säkerhetskopia när du försöker skriva ut objektet eller konvertera det till en sträng. Så det är ofta en bra idé defiavsluta åtminstone __repr__
, även om du inte gör det defikommer ut __str__
.
Så här kunde vi defiförneka __repr__
för vårt pizzaexempel:
klass pizza:
def __init__(själv, storlek, toppings):
self.size = storlek
self.toppings = toppings
def __repr__(själv):
return f"Pizza('{self.size}', {self.toppings})"
my_pizza = Pizza('stor', ['pepperoni', 'svamp'])
print(repr(min_pizza)) # Detta kommer att skriva ut: Pizza('stor', ['pepperoni', 'svamp'])
__repr__
ger dig en sträng som du kan köra som ett Python-kommando för att återskapa pizzaobjektet __str__
ger dig en mer mänsklig beskrivning. Jag hoppas att det hjälper dig att tugga dessa dundermetoder lite bättre!
I Python vet vi alla att det är möjligt att lägga till siffror med operatorn +
, Som 3 + 5
.
Men vad händer om vi vill lägga till instanser av något anpassat objekt?
Dunderfunktionen __add__
det tillåter oss att göra just det. Det ger oss förmågan att definish operatörens beteende +
på våra personliga föremål.
För konsekvensens intresse, låt oss anta att vi vill defiavsluta beteendet av +
på vårt pizzaexempel. Låt oss säga att när vi lägger till två eller flera pizzor tillsammans, kommer det automatiskt att kombinera alla deras pålägg. Så här kan det se ut:
klass pizza:
def __init__(själv, storlek, toppings):
self.size = storlek
self.toppings = toppings
def __add__(själv, annat):
om inte är instans (annan, Pizza):
raise TypeError("Du kan bara lägga till en annan pizza!")
new_toppings = self.toppings + other.toppings
returnera pizza(self.size, new_topings)
# Låt oss skapa två pizzor
pizza1 = Pizza('stor', ['pepperoni', 'svamp'])
pizza2 = Pizza('stor', ['oliver', 'ananas'])
# Och låt oss nu "lägga till" dem
kombinerad_pizza = pizza1 + pizza2
print(combined_pizza.toppings) # Detta kommer att skriva ut: ['pepperoni', 'svamp', 'oliver', 'ananas']
På samma sätt som dunder __add__
, vi kan också defiavsluta andra aritmetiska funktioner som t.ex __sub__
(genom subtraktion med operatorn -
) Och __mul__
(för multiplikation med operatorn *
).
Denna dunder-metod tillåter oss att defiavsluta vad funktionen len()
måste returnera för våra skräddarsydda varor.
Python använder len()
för att få längden eller storleken på en datastruktur som en lista eller sträng.
I samband med vårt exempel skulle vi kunna säga att "längden" på en pizza är antalet pålägg den har. Så här kan vi implementera det:
klass pizza:
def __init__(själv, storlek, toppings):
self.size = storlek
self.toppings = toppings
def __len__(själv):
return len(self.toppings)
# Låt oss skapa en pizza
my_pizza = Pizza('stor', ['pepperoni', 'svamp', 'oliver'])
print(len(my_pizza)) # Detta kommer att skriva ut: 3
I metoden __len__ returnerar vi bara längden på listan toppings
. Nu, len(my_pizza)
det kommer att berätta för oss hur många pålägg som finns på den my_pizza
.
Denna dunder-metod tillåter objekt att vara itererbara, dvs den kan användas i en for-loop.
För att göra detta måste vi också defiavsluta funktionen __next__
, Detta används för defiavsluta beteendet som ska returnera nästa värde i iterationen. Det bör också signalera det iterbara vid händelsen att det inte finns fler element i sekvensen. Vi uppnår vanligtvis detta genom att göra ett undantag StopIteration
.
För vårt pizzaexempel, låt oss säga att vi vill upprepa påläggen. Vi skulle kunna göra vår pizzaklass iterabel definendo en metod __iter__
:
klass pizza:
def __init__(själv, storlek, toppings):
self.size = storlek
self.toppings = toppings
def __iter__(själv):
själv.n = 0
återvända själv
def __nästa__(själv):
if self.n < len(self.toppings):
resultat = self.toppings[self.n]
själv.n += 1
returnera resultatet
annan:
höja StopIteration
# Låt oss skapa en pizza
my_pizza = Pizza('stor', ['pepperoni', 'svamp', 'oliver'])
# Och låt oss nu iterera över det
för topping i min_pizza:
print (toppning)
I det här fallet för loop-anrop __iter__
, som initierar en räknare (self.n)
och returnerar själva pizzaobjektet (self)
.
Sedan, for loop-samtal __next__
för att få varje topping i tur och ordning.
När __next__
lämnade tillbaka alla kryddor, StopIteration
det ger ett undantag och for-slingan vet nu att det inte finns några fler pålägg och kommer därför att avbryta iterationsprocessen.
Ercole Palmeri
Marinesektorn är en sann global ekonomisk makt, som har navigerat mot en marknad på 150 miljarder...
I måndags tillkännagav Financial Times ett avtal med OpenAI. FT licensierar sin journalistik i världsklass...
Miljontals människor betalar för streamingtjänster och betalar månatliga prenumerationsavgifter. Det är en allmän uppfattning att du...
Coveware by Veeam kommer att fortsätta att tillhandahålla svarstjänster för cyberutpressning. Coveware kommer att erbjuda kriminaltekniska och saneringsmöjligheter...