Yn 'e grutte wrâld fan Python-programmearring is d'r in set funksjes dy't faaks ûngemurken geane troch begjinners, mar dochs in wichtich belang hawwe yn it ekosysteem fan 'e taal.
Magic metoaden binne in set fan pre metoadendefinites yn Python dy't spesjale syntaktyske funksjes leverje. Se wurde maklik werkend troch harren dûbele streepkes oan it begjin en ein, lykas __init__, __call__, __len__
… ensfh.
Magic metoaden tastean oanpaste objekten te gedragen fergelykber mei ynboude Python typen.
Yn dit artikel sille wy rjochtsje op 'e krêftige dunder-funksjes. Wy sille har doel ûndersykje en har gebrûk beprate.
Oft jo in Python-novice binne as in betûfte programmeur, dit artikel is fan doel jo in wiidweidich begryp te jaan fan Dunder-funksjes, wêrtroch jo Python-kodearringsûnderfining effisjinter en nofliker wurdt.
Unthâld, de magy fan Python leit net allinich yn syn ienfâld en veelzijdigheid, mar ek yn syn krêftige funksjes lykas Dunder-funksjes.
Miskien wol de meast basale dunderfunksje fan allegear. Dit is de magyske metoade dy't Python automatysk ropt as wy in nij objekt meitsje (of lykas de namme oanjout, inisjalisearje).__init__
klasse pizza:
def __init__(sels, grutte, toppings):
self.size = grutte
self.toppings = toppings
# Litte wy no in pizza meitsje
my_pizza = Pizza('grut', ['pepperoni', 'mushrooms'])
print(my_pizza.size) # Dit sil printsje: grut
print(my_pizza.toppings) # Dit sil printsje: ['pepperoni', 'mushrooms']
Yn dit foarbyld wurdt in klasse neamd Pizza makke. Wy hawwe ús funksje __init__ ynsteld om de parameters op te nimmen dy't moatte wurde oantsjutte by inisjalisaasjetiid, en set se as eigenskippen foar ús oanpaste objekt.
Hjir wurdt it brûkt om it eksimplaar fan 'e klasse te fertsjintwurdigjen. Dus as wy self.size = grutte skriuwe, sizze wy: "Hey, dit pizza-objekt hat in attribútgrutte size
, en ik wol dat it elke grutte is dy't ik levere doe't ik it objekt makke.
Dit is de magyske metoade fan Python wêrmei wy kinne definish in beskriuwing foar ús oanpaste item.
As jo in objekt printsje of it konvertearje nei in tekenrige mei str()
, Python kontrolearje as jo hawwe defiIk haw in metoade betocht __str__
foar de klasse fan dat objekt.
As dat sa is, brûk dy metoade om it objekt yn in tekenrige te konvertearjen.
Wy kinne ús Pizza-foarbyld útwreidzje om in funksje op te nimmen __str__
as folget:
klasse Pizza: def __init__(self, grutte, toppings): self.size = grutte self.toppings = toppings def __str__(self): return f"A {self.size} pizza mei {', '.join(self.toppings )}" my_pizza = Pizza('grut', ['pepperoni', 'mushrooms']) print(my_pizza) # Dit sil printsje: In grutte pizza mei pepperoni, paddestoelen
__repr__
De funksje __str__ is mear in ynformele manier om de eigenskippen fan in objekt te beskriuwen. Oan 'e oare kant wurdt __repr__ brûkt om in mear formele, detaillearre en ûndûbelsinnige beskriuwing fan it oanpaste objekt te jaan.
As jo belje repr()
op in objekt of jo typ de objektnamme gewoan yn 'e konsole, Python sil sykje nei in metoade __repr__
.
Se __str__
it is net definite, Python sil brûke __repr__
as reservekopy by it besykjen om it objekt te printsjen of te konvertearjen nei in tekenrige. Sa is it faaks in goed idee defifinish op syn minst __repr__
, sels as jo dat net dogge defikomt út __str__
.
Hjir is hoe't wy koenen defiein __repr__
foar ús pizza foarbyld:
klasse pizza:
def __init__(sels, grutte, toppings):
self.size = grutte
self.toppings = toppings
def __repr__(sels):
return f"Pizza('{self.size}', {self.toppings})"
my_pizza = Pizza('grut', ['pepperoni', 'mushrooms'])
print(repr(my_pizza)) # Dit sil printsje: Pizza('grut', ['pepperoni', 'mushrooms'])
__repr__
jout jo in tekenrige dy't jo kinne útfiere as in Python-kommando om it pizza-objekt opnij oan te meitsjen, wylst __str__
jout jo in mear minsklike beskriuwing. Ik hoopje dat it jo helpt om dizze dundermetoaden in bytsje better te kauwen!
Yn Python witte wy allegear dat it mooglik is om nûmers ta te foegjen mei de operator +
, kom 3 + 5
.
Mar wat as wy eksimplaren fan wat oanpast foarwerp taheakje wolle?
De dunder funksje __add__
it lit ús krekt dat dwaan. It jout ús de mooglikheid om definish it gedrach fan de operator +
op ús persoanlike items.
Lit ús yn it belang fan konsistinsje oannimme dat wy dat wolle defifinish it gedrach fan +
op ús pizza foarbyld. Litte wy sizze dat elke kear as wy twa of mear pizza's byinoar tafoegje, sil it automatysk al har toppings kombinearje. Hjir is hoe't it der útsjen kin:
klasse pizza:
def __init__(sels, grutte, toppings):
self.size = grutte
self.toppings = toppings
def __add__ (sels, oar):
as it net is (oars, pizza):
raise TypeError ("Jo kinne allinich in oare pizza tafoegje!")
new_toppings = self.toppings + other.toppings
return Pizza(self.size, new_toppings)
# Litte wy twa pizza's meitsje
pizza1 = Pizza('grut', ['pepperoni', 'mushrooms'])
pizza2 = Pizza('grut', ['oliven', 'ananas'])
# En litte wy se no "taheakje".
combined_pizza = pizza1 + pizza2
print(combined_pizza.toppings) # Dit sil printsje: ['pepperoni', 'mushrooms', 'olives', 'ananas']
Krekt as dunder __add__
, wy kinne ek defifinish oare arithmetic funksjes lykas __sub__
(troch subtraksje mei de operator -
) en __mul__
(foar fermannichfâldigjen mei de operator *
).
Dizze dunder metoade lit ús ta defifinish wat de funksje len()
moat weromkomme foar ús oanpaste items.
Python brûkt len()
om de lingte of grutte fan in gegevensstruktuer te krijen, lykas in list of tekenrige.
Yn 'e kontekst fan ús foarbyld kinne wy sizze dat de "lingte" fan in pizza it oantal toppings is dy't it hat. Hjir is hoe't wy it kinne ymplementearje:
klasse pizza:
def __init__(sels, grutte, toppings):
self.size = grutte
self.toppings = toppings
def __len__(sels):
return len(self.toppings)
# Litte wy in pizza meitsje
my_pizza = Pizza('grut', ['pepperoni', 'paddestoelen', 'oliven'])
print(len(my_pizza)) # Dit sil printsje: 3
Yn de metoade __len__, wy allinne werom de lingte fan de list toppings
, No, len(my_pizza)
it sil ús fertelle hoefolle toppings derop binne my_pizza
.
Dizze dundermetoade lit objekten iterabel wêze, d.w.s. it kin brûkt wurde yn in for-loop.
Om dit te dwaan, moatte wy ek defifinish de funksje __next__
, Dit wurdt brûkt foar definish it gedrach dat moat weromkomme de folgjende wearde yn de iteraasje. It moat ek it iterabele sinjalearje op it evenemint dat d'r gjin eleminten mear binne yn 'e folchoarder. Wy berikke dit typysk troch in útsûndering te smiten StopIteration
.
Foar ús pizza-foarbyld, litte wy sizze dat wy de toppings wolle iterearje. Wy kinne ús Pizza-klasse iterabel meitsje definendo in metoade __iter__
:
klasse pizza:
def __init__(sels, grutte, toppings):
self.size = grutte
self.toppings = toppings
def __iter__(sels):
sels.n = 0
werom sels
def __next__(sels):
if self.n < len(self.toppings):
result = self.toppings[self.n]
sels.n += 1
werom resultaat
oars:
ferheegje StopIteration
# Litte wy in pizza meitsje
my_pizza = Pizza('grut', ['pepperoni', 'paddestoelen', 'oliven'])
# En lit ús der no oer iterearje
foar topping yn my_pizza:
print (topping)
Yn dit gefal ropt de foar-loop __iter__
, dy't in teller inisjalisearret (self.n)
en jout de pizza foarwerp sels (self)
.
Dan ropt de foar-loop __next__
om elke topping op syn beurt te krijen.
wannear __next__
joech alle krûden werom, StopIteration
it smyt in útsûndering en de for-lus wit no dat der gjin toppings mear binne en sa sil it iteraasjeproses ôfbrekke.
Ercole Palmeri
De marinesektor is in wiere wrâldwide ekonomyske macht, dy't navigearre is nei in merk fan 150 miljard ...
Ofrûne moandei kundige de Financial Times in deal oan mei OpenAI. FT lisinsje har sjoernalistyk fan wrâldklasse ...
Miljoenen minsken betelje foar streamingtsjinsten, beteljen moanlikse abonnemintskosten. It is gewoane miening dat jo ...
Coveware troch Veeam sil trochgean mei it leverjen fan antwurdtsjinsten foar cyberafpersing ynsidint. Coveware sil forensyske en sanearjen mooglikheden oanbiede ...