Python-ի ծրագրավորման հսկայական աշխարհում կա մի շարք առանձնահատկություններ, որոնք հաճախ աննկատ են մնում սկսնակների կողմից, բայց զգալի նշանակություն ունեն լեզվի էկոհամակարգում:
Կախարդական մեթոդները նախնական մեթոդների մի շարք ենdefinites Python-ում, որոնք ապահովում են հատուկ շարահյուսական հատկանիշներ: Նրանք հեշտությամբ ճանաչվում են սկզբում և վերջում իրենց կրկնակի գծիկներով, ինչպես __init__, __call__, __len__
… և այլն:
Կախարդական մեթոդները թույլ են տալիս հարմարեցված օբյեկտներին վարվել այնպես, ինչպես ներկառուցված Python տեսակները:
Այս հոդվածում մենք կկենտրոնանանք հզոր Dunder գործառույթների վրա: Մենք կուսումնասիրենք դրանց նպատակը և կքննարկենք դրանց օգտագործումը:
Անկախ նրանից՝ դուք Python-ի սկսնակ եք, թե փորձառու ծրագրավորող, այս հոդվածը նպատակ ունի ձեզ տրամադրել Dunder գործառույթների համապարփակ պատկերացում՝ դարձնելով ձեր Python կոդավորման փորձն ավելի արդյունավետ և հաճելի:
Հիշեք, որ Python-ի հմայքը կայանում է ոչ միայն նրա պարզության և բազմակողմանիության մեջ, այլ նաև նրա հզոր հատկանիշների մեջ, ինչպիսիք են Dunder ֆունկցիաները:
Թերևս ամենատարրական դանդերի գործառույթը: Սա կախարդական մեթոդ է, որը Python-ը ավտոմատ կերպով կանչում է, երբ մենք ստեղծում ենք (կամ ինչպես անունն է հուշում, սկզբնավորում ենք) նոր օբյեկտ։__init__
դասի Պիցցա:
def __init__(ինքնուրույն, չափ, լցոնումներ):
self.size = չափ
self.toppings = լցոնումներ
# Հիմա եկեք պիցցա ստեղծենք
my_pizza = Պիցցա ('մեծ', ['պեպպերոնի', 'սնկով'])
print(my_pizza.size) # Սա տպելու է՝ մեծ
print(my_pizza.toppings) # Սա կտպագրի՝ ['pepperoni', 'shumrooms']
Այս օրինակում ստեղծվում է Պիցցա անունով դաս: Մենք կարգավորեցինք մեր __init__ ֆունկցիան, որպեսզի ներառի այն պարամետրերը, որոնք պետք է նշվեն սկզբնավորման ժամանակ և սահմանեցինք դրանք որպես հատկություններ մեր հատուկ օբյեկտի համար:
Այստեղ այն օգտագործվում է դասի օրինակը ներկայացնելու համար: Այսպիսով, երբ մենք գրում ենք self.size = չափը, մենք ասում ենք. «Հեյ, այս պիցցայի օբյեկտն ունի հատկանիշի չափ size
, և ես ուզում եմ, որ այն լինի ինչ չափի, որ ես տրամադրել եմ օբյեկտը ստեղծելիս»:
Սա Python-ի կախարդական մեթոդն է, որը մեզ թույլ է տալիս definish նկարագրությունը մեր հատուկ ապրանքի համար:
Երբ դուք տպում եք որևէ առարկա կամ այն վերածում տողի՝ օգտագործելով str()
, Python-ով ստուգեք, եթե ունեք defiԵս մի մեթոդ եմ հորինել __str__
այդ օբյեկտի դասի համար:
Եթե այո, ապա օգտագործեք այդ մեթոդը՝ օբյեկտը տողի փոխարկելու համար:
Մենք կարող ենք ընդլայնել մեր Պիցցայի օրինակը՝ ներառելով գործառույթ __str__
հետևյալը.
դաս Պիցցա՝ def __init__(self, չափ, toppings): self.size = size self.toppings = toppings def __str__(self): return f"A {self.size} pizza with {', '.join(self.toppings): )}" my_pizza = Պիցցա('մեծ', ['պեպպերոնի', 'սնկով']) print(my_pizza) # Սա տպելու է՝ Պեպպերոնիով մեծ պիցցա, սնկով
__repr__
__str__ ֆունկցիան ավելի շուտ օբյեկտի հատկությունները նկարագրելու ոչ պաշտոնական եղանակ է: Մյուս կողմից, __repr__-ն օգտագործվում է մաքսային օբյեկտի ավելի պաշտոնական, մանրամասն և միանշանակ նկարագրություն տրամադրելու համար:
Եթե զանգահարեք repr()
օբյեկտի վրա կամ պարզապես մուտքագրեք օբյեկտի անունը վահանակի մեջ, Python-ը կփնտրի մեթոդ __repr__
.
Se __str__
դա չէ definite, Python-ը կօգտագործի __repr__
որպես պահեստային, երբ փորձում եք տպել օբյեկտը կամ փոխարկել այն տողի: Այսպիսով, դա հաճախ լավ գաղափար է defiվերջացնել գոնե __repr__
, նույնիսկ եթե չես անում defiդուրս է գալիս __str__
.
Ահա թե ինչպես կարող էինք defiավարտել __repr__
մեր պիցցայի օրինակի համար.
դասի Պիցցա:
def __init__(ինքնուրույն, չափ, լցոնումներ):
self.size = չափ
self.toppings = լցոնումներ
Def __repr __ (ինքնուրույն).
վերադարձնել f"Pizza('{self.size}', {self.toppings})"
my_pizza = Պիցցա ('մեծ', ['պեպպերոնի', 'սնկով'])
print(repr(my_pizza)) # Սա կտպվի՝ Պիցցա ('մեծ', ['պեպպերոնի', 'սնկով'])
__repr__
տալիս է տող, որը կարող եք գործարկել որպես Python հրաման՝ պիցցայի օբյեկտը վերստեղծելու համար, մինչդեռ __str__
ձեզ ավելի մարդկային նկարագրություն է տալիս: Հուսով եմ, որ դա կօգնի ձեզ մի փոքր ավելի լավ ծամել այս կեղտոտ մեթոդները:
Python-ում բոլորս գիտենք, որ օպերատորի միջոցով հնարավոր է թվեր ավելացնել +
, As 3 + 5
.
Բայց ինչ անել, եթե մենք ցանկանում ենք ավելացնել որոշ հատուկ օբյեկտի օրինակներ:
Դանդերի ֆունկցիան __add__
դա մեզ թույլ է տալիս հենց դա անել: Դա մեզ հնարավորություն է տալիս defiզսպել օպերատորի պահվածքը +
մեր անհատականացված իրերի վրա:
Հետևողականության շահերից ելնելով, ենթադրենք, որ ուզում ենք defiավարտել վարքագիծը +
մեր պիցցայի օրինակով: Ենթադրենք, որ երբ մենք ավելացնենք երկու կամ ավելի պիցցա միասին, այն ավտոմատ կերպով կմիավորի դրանց բոլոր լցոնումները: Ահա թե ինչ կարող է նման լինել.
դասի Պիցցա:
def __init__(ինքնուրույն, չափ, լցոնումներ):
self.size = չափ
self.toppings = լցոնումներ
def __add__(ես, այլ):
եթե ոչ օրինակ (այլ, Պիցցա):
բարձրացնել TypeError («Դուք կարող եք ավելացնել միայն մեկ այլ Պիցցա»)
new_toppings = self.toppings + other.toppings
վերադարձի պիցցա (self.size, new_toppings)
# Ստեղծենք երկու պիցցա
pizza1 = Պիցցա ('մեծ', ['պեպպերոնի', 'սնկով'])
pizza2 = Պիցցա ('մեծ', ['ձիթապտուղ', 'արքայախնձոր'])
# Իսկ հիմա եկեք «ավելացնենք» դրանք
համակցված_պիցցա = պիցցա1 + պիցցա2
print(combined_pizza.toppings) # Սա կտպագրի՝ ['պեպպերոնի', 'սնկով', 'ձիթապտուղ', 'արքայախնձոր']
Դանդերի նման __add__
, մենք նույնպես կարող ենք defiավարտել այլ թվաբանական ֆունկցիաներ, ինչպիսիք են __sub__
(օպերատորի միջոցով հանում -
) Եվ __mul__
(օպերատորի միջոցով բազմապատկելու համար *
).
Դանդերի այս մեթոդը մեզ թույլ է տալիս defiավարտել այն, ինչ գործառույթը len()
պետք է վերադառնա մեր հարմարեցված իրերի համար:
Python-ի օգտագործումը len()
ստանալ տվյալների կառուցվածքի երկարությունը կամ չափը, ինչպիսիք են ցուցակը կամ տողը:
Մեր օրինակի համատեքստում կարելի է ասել, որ պիցցայի «երկարությունը» նրա մեջ եղած հավելումների քանակն է։ Ահա թե ինչպես մենք կարող ենք այն իրականացնել.
դասի Պիցցա:
def __init__(ինքնուրույն, չափ, լցոնումներ):
self.size = չափ
self.toppings = լցոնումներ
def __len__(self):
հետադարձ լինզան (self.topings)
# Եկեք պիցցա ստեղծենք
my_pizza = Պիցցա ('մեծ', ['պեպպերոնի', 'սնկով', 'ձիթապտուղ'])
print(len(my_pizza)) # Սա տպելու է՝ 3
__len__ մեթոդում մենք վերադարձնում ենք միայն ցանկի երկարությունը toppings
, Հիմա, len(my_pizza)
այն մեզ կասի, թե քանի տոփինգ կա դրա վրա my_pizza
.
Այս Dunder մեթոդը թույլ է տալիս օբյեկտներին կրկնվող լինել, այսինքն՝ այն կարող է օգտագործվել for loop-ում:
Դա անելու համար մենք նույնպես պետք է defiավարտել գործառույթը __next__
, Սա օգտագործվում է definish վարքագիծը, որը պետք է վերադարձնի հաջորդ արժեքը կրկնության մեջ: Այն նաև պետք է ազդարարի կրկնվողը այն դեպքի համար, որ հաջորդականության մեջ այլևս տարրեր չկան: Մենք սովորաբար դրան հասնում ենք բացառություն գցելով StopIteration
.
Մեր պիցցայի օրինակի համար ասենք, որ ուզում ենք կրկնել լցոնումները: Մենք կարող ենք մեր Պիցցայի դասը դարձնել կրկնվող definendo մի մեթոդ __iter__
:
դասի Պիցցա:
def __init__(ինքնուրույն, չափ, լցոնումներ):
self.size = չափ
self.toppings = լցոնումներ
def __iter__(self):
ինքնուրույն.n = 0
վերադարձնել ինքն իրեն
def __next__(self):
if self.n < len(self.toppings):
արդյունք = self.toppings[self.n]
ինքնուրույն.n += 1
վերադարձի արդյունքը
այլ:
բարձրացնել StopIteration
# Եկեք պիցցա ստեղծենք
my_pizza = Պիցցա ('մեծ', ['պեպպերոնի', 'սնկով', 'ձիթապտուղ'])
# Եվ հիմա եկեք կրկնենք դրա մասին
my_pizza-ում լցնելու համար.
տպագրություն (գլխավոր)
Այս դեպքում for loop-ը կանչում է __iter__
, որը սկզբնավորում է հաշվիչը (self.n)
և ինքն է վերադարձնում պիցցայի առարկան (self)
.
Այնուհետև, for loop-ը կանչում է __next__
յուրաքանչյուր լիցքավորումը հերթով ստանալու համար:
երբ __next__
վերադարձրեց բոլոր համեմունքները, StopIteration
այն բացառություն է անում, և for loop-ն այժմ գիտի, որ այլևս լրացումներ չկան, և այդպիսով կդադարեցնի կրկնման գործընթացը:
Ercole Palmeri
Կատանիայի պոլիկլինիկայում ակնաբուժական վիրահատություն է կատարվել Apple Vision Pro գովազդային հեռուստադիտողի միջոցով…
Գունավորելու միջոցով նուրբ շարժիչ հմտությունների զարգացումը երեխաներին պատրաստում է ավելի բարդ հմտությունների, ինչպիսին է գրելը: Գունավորելու…
Ծովային ոլորտը իսկական համաշխարհային տնտեսական տերություն է, որը նավարկվել է դեպի 150 միլիարդանոց շուկա...
Անցյալ երկուշաբթի Financial Times-ը հայտարարեց OpenAI-ի հետ գործարքի մասին: FT-ն արտոնագրում է իր համաշխարհային մակարդակի լրագրությունը…