I den store verden af Python-programmering er der et sæt funktioner, der ofte går ubemærket hen af begyndere, men som alligevel har en væsentlig betydning i sprogets økosystem.
Magiske metoder er et sæt præ-metoderdefinites i Python, der giver specielle syntaktiske funktioner. De er let genkendelige på deres dobbelte streger i begyndelsen og slutningen, f.eks __init__, __call__, __len__
… etc.
Magiske metoder tillader brugerdefinerede objekter at opføre sig på samme måde som indbyggede Python-typer.
I denne artikel vil vi fokusere på de kraftfulde dunder-funktioner. Vi vil undersøge deres formål og diskutere deres brug.
Uanset om du er en Python-novice eller en erfaren programmør, har denne artikel til formål at give dig en omfattende forståelse af Dunder-funktioner, hvilket gør din Python-kodningsoplevelse mere effektiv og behagelig.
Husk, at magien ved Python ikke kun ligger i dens enkelhed og alsidighed, men også i dens kraftfulde funktioner som Dunder-funktioner.
Måske den mest basale dunder-funktion af alle. Dette er den magiske metode, som Python automatisk kalder, når vi opretter (eller som navnet antyder, initialiserer) et nyt objekt.__init__
klasse pizza:
def __init__(selv, størrelse, toppings):
self.size = størrelse
self.toppings = toppings
# Lad os nu lave en pizza
my_pizza = Pizza('stor', ['pepperoni', 'svampe'])
print(my_pizza.size) # Dette vil udskrive: large
print(my_pizza.toppings) # Dette vil udskrive: ['pepperoni', 'svampe']
I dette eksempel oprettes en klasse kaldet Pizza. Vi konfigurerer vores __init__-funktion til at inkludere de parametre, der skal specificeres på initialiseringstidspunktet, og indstiller dem som egenskaber for vores brugerdefinerede objekt.
Her bruges det til at repræsentere forekomsten af klassen. Så når vi skriver self.size = størrelse, siger vi, "Hey, dette pizzaobjekt har en attributstørrelse size
, og jeg vil have, at den skal have den størrelse, jeg angav, da jeg oprettede objektet”.
Dette er Pythons magiske metode, der giver os mulighed for det definish en beskrivelse af vores brugerdefinerede vare.
Når du udskriver et objekt eller konverterer det til en streng vha str()
, Python tjek om du har defiJeg har fundet på en metode __str__
for det pågældende objekts klasse.
Hvis ja, brug denne metode til at konvertere objektet til en streng.
Vi kan udvide vores Pizza-eksempel til at omfatte en funktion __str__
som følger:
klasse Pizza: def __init__(selv, størrelse, toppings): self.size = størrelse self.toppings = toppings def __str__(self): returner f"A {self.size} pizza med {', '.join(self.toppings )}" my_pizza = Pizza('stor', ['pepperoni', 'svampe']) print(min_pizza) # Dette vil udskrive: En stor pizza med pepperoni, svampe
__repr__
Funktionen __str__ er mere en uformel måde at beskrive et objekts egenskaber. På den anden side bruges __repr__ til at give en mere formel, detaljeret og utvetydig beskrivelse af det brugerdefinerede objekt.
Hvis du ringer repr()
på et objekt eller du bare skriver objektnavnet i konsollen, vil Python lede efter en metode __repr__
.
Se __str__
det er ikke definite, vil Python bruge __repr__
som backup, når du forsøger at udskrive objektet eller konvertere det til en streng. Så det er ofte en god idé defifærdig i det mindste __repr__
, selvom du ikke gør det defidejligt __str__
.
Her er hvordan vi kunne definægte __repr__
for vores pizza eksempel:
klasse pizza:
def __init__(selv, størrelse, toppings):
self.size = størrelse
self.toppings = toppings
def __repr__(selv):
return f"Pizza('{selv.størrelse}', {self.toppings})"
my_pizza = Pizza('stor', ['pepperoni', 'svampe'])
print(repr(min_pizza)) # Dette vil udskrive: Pizza('large', ['pepperoni', 'svampe'])
__repr__
giver dig en streng, som du kan køre som en Python-kommando for at genskabe pizzaobjektet __str__
giver dig en mere menneskelig beskrivelse. Jeg håber, det hjælper dig med at tygge disse dunder-metoder lidt bedre!
I Python ved vi alle, at det er muligt at tilføje tal ved hjælp af operatoren +
, Som 3 + 5
.
Men hvad hvis vi vil tilføje forekomster af et eller andet tilpasset objekt?
Dunder-funktionen __add__
det giver os mulighed for at gøre netop det. Det giver os evnen til definish operatørens adfærd +
på vores personlige varer.
Af hensyn til sammenhængen, lad os antage, at vi ønsker det defiafslutte adfærden af +
på vores pizzaeksempel. Lad os sige, at når vi tilføjer to eller flere pizzaer sammen, vil det automatisk kombinere alle deres toppings. Sådan kan det se ud:
klasse pizza:
def __init__(selv, størrelse, toppings):
self.size = størrelse
self.toppings = toppings
def __add__(selv, andet):
hvis ikke er en instans (andet, pizza):
raise TypeError("Du kan kun tilføje endnu en pizza!")
new_toppings = self.toppings + other.toppings
returner pizza(selv.størrelse, nye_toppings)
# Lad os lave to pizzaer
pizza1 = Pizza('stor', ['pepperoni', 'svampe'])
pizza2 = Pizza('stor', ['oliven', 'ananas'])
# Og lad os nu "føje" dem
kombineret_pizza = pizza1 + pizza2
print(combined_pizza.toppings) # Dette vil udskrive: ['pepperoni', 'svampe', 'oliven', 'ananas']
På samme måde som dunder __add__
, det kan vi også defiafslutte andre regnefunktioner som f.eks __sub__
(ved at trække fra ved hjælp af operatoren -
) Og __mul__
(til multiplikation ved hjælp af operatoren *
).
Denne dunder-metode giver os mulighed for defiafslutte hvad funktionen len()
skal returnere for vores tilpassede varer.
Python bruger len()
for at få længden eller størrelsen af en datastruktur, såsom en liste eller streng.
I forbindelse med vores eksempel kunne vi sige, at "længden" af en pizza er antallet af toppings, den har. Sådan kunne vi implementere det:
klasse pizza:
def __init__(selv, størrelse, toppings):
self.size = størrelse
self.toppings = toppings
def __len__(selv):
returnere len(selv.toppings)
# Lad os lave en pizza
my_pizza = Pizza('stor', ['pepperoni', 'svampe', 'oliven'])
print(len(my_pizza)) # Dette vil udskrive: 3
I __len__ metoden returnerer vi kun længden af listen toppings
. Nu, len(my_pizza)
det vil fortælle os, hvor mange toppings der er på den my_pizza
.
Denne dunder-metode tillader objekter at være iterable, dvs. den kan bruges i en for-løkke.
For at gøre dette skal vi også defiafslutte funktionen __next__
, Dette bruges til defiafslutte den adfærd, der skulle returnere den næste værdi i iterationen. Det skal også signalere det iterable i hændelsen, at der ikke er flere elementer i sekvensen. Det opnår vi typisk ved at smide en undtagelse StopIteration
.
For vores pizzaeksempel, lad os sige, at vi vil gentage toppings. Vi kunne gøre vores pizzaklasse iterable definendo en metode __iter__
:
klasse pizza:
def __init__(selv, størrelse, toppings):
self.size = størrelse
self.toppings = toppings
def __iter__(selv):
selv.n = 0
returnere selv
def __næste__(selv):
if self.n < len(self.toppings):
resultat = self.toppings[self.n]
self.n += 1
returnere resultat
andet:
hæve StopIteration
# Lad os lave en pizza
my_pizza = Pizza('stor', ['pepperoni', 'svampe', 'oliven'])
# Og lad os nu gentage det
til topping i min_pizza:
print (topping)
I dette tilfælde for loop-opkald __iter__
, som initialiserer en tæller (self.n)
og returnerer selve pizzaobjektet (self)
.
Derefter for loop opkald __next__
at få hver topping på skift.
når __next__
returnerede alle krydderier, StopIteration
det giver en undtagelse, og for-løkken ved nu, at der ikke er flere toppings, og vil derfor afbryde iterationsprocessen.
Ercole Palmeri
Coveware by Veeam vil fortsætte med at levere responstjenester til cyberafpresning. Coveware vil tilbyde kriminaltekniske og afhjælpende funktioner...
Forudsigende vedligeholdelse revolutionerer olie- og gassektoren med en innovativ og proaktiv tilgang til anlægsstyring...
Det britiske CMA har udsendt en advarsel om Big Techs adfærd på markedet for kunstig intelligens. Der…
Dekretet om "grønne huse", der er formuleret af Den Europæiske Union for at øge bygningers energieffektivitet, har afsluttet sin lovgivningsproces med...