#32 DUNDER METODLAR
Pythondagi maxsus metodlar bilan tanishamiz.
MAXSUS METODLAR
Pythonda obyektlar bilan ishlashni yanada qulay qilish uchun bir nechta maxsus metodlar bor. Bu metodlarning nomi ikki pastki chiziq bilan yozilgani uchun, double underscore yoki qisqa qilib dunder metodlar deb ataladi. Dunder metolar yordamida obyektlarga qo'shimcha qulayliklar va vazifalar qo'shishimiz mumkin. Klass yoki obyektga oid dunder metodlar ro'yxatini ko'rish uchun dir() funksiyasidan foydalanamiz:
Dunder metodlardan biz __init__
metodi bilan tanishdik. Bu metod klassdan obyekt yaratishda chaqiriladi va obyektning xususiyatlarini belgilaydi. Ushbu darsimizda esa maxsus metodlarning ba'zilari bilan tanishamiz.
OBYEKT HAQIDA MA'LUMOT
Obyektga print()
yoki str()
orqali murojat qilinganda obyekt haqida tushunarli ma'lumot qaytarish uchun __repr__
va __str__
metodlaridan foydalanamiz. Tushunarli bo'lishi uchun avvalgi darsimizdagi Avto
klassiga qaytamiz:
Yuqoridagi klassdan yangi obyekt yaratamiz va obyekt haqida ma'lumot olish uchun print()
funksiyasini chaqiramiz:
Natija: <__main__.Avto object at 0x00000238A6DAE0C8>
Qandaydur tushunarsiz ma'lumot. Ekrandagi natijadan biz faqat avto1
obyektimiz Avto
klassiga tegishli ekanini ko'ramiz. Qanday qilib shuning o'rniga obyekt haqida tushunarliroq ma'lumot olishimiz mumkin?
Gap shundaki biz har gal obyketga print()
(yoki str()
yoki repr()
) orqali murojat qilganimizda, Python obyket ichida __str__
yoki __repr__
metodlariga murojat qiladi. Agar biz bu metodlarni yozmagan bo'lsak, yuqoridagi kabi umumiy ma'lumot qayataradi.
Biz ushbu metodlarni yangidan yozib, biz istagan ma'lumotni qayataradian qilishimiz mumkin. Odatda, yuqoridagi ikki metoddan birini yozish kifoya. Odatda, __repr__
umumiyorq, __str__
esa batafsilroq ma'lumot olish uchun ishlatiladi.
Ikkalasidan birini tanlaganda, __repr__
metodiga yon bosiladi, sababi bu metod print()
, str()
va repr()
funksiyalarining hammasi bilan ishlaydi. Keling biz ham yuoqirdagi klassimizga__repr__
metodini qo'shamiz:
Qaytadan print()
funksiyasini chaqiramiz:
Natija: Avto: Qora GM Malibu
Mana endi natijamiz ancha tushunarli ko'rinishda chiqdi.
OBYEKTLARNI TAQQOSLASH
Taqqoslash operatorlari yordamida biz turli obyektlarni solishtirishimiz mumkin. Taqqoslash natijasi mantiqiy qiymat (True
yoki False
) ko'rinishida bo'ladi.
Natija: False
Keling endi Avto klassidan 2 ta obyekt yaratamiz, va ularni taqqoslab ko'ramiz:
Natija: TypeError: '>' not supported between instances of 'Avto' and 'Avto'
Xatolik. Demak bu ikki obyektni solshtirib bo'lmas ekan.
Biz taqqolash operatorlariga murojat qilganimizda, Python obyektlar ichida taqqoslash uchun maxsus metodlarni qidiradi, agar metodlar topilmasa yuqoridagi kabi TypeError
qaytaradi.
Taqqoslash metodlari quyidagilardan iborat:
Metod | Operator |
|
|
|
|
|
|
|
|
|
|
|
|
Yuqoridagi obyektlardan yarmi uchun metodlar yozishimiz kifoya, misol uchun __lt__
(x<y) metodini yozsak, __gt__
(x>y) metodini yozishimiz shart emas, yoki __le__
metodi, __ge__
metodini ham o'z ichiga oladi, va hokazo.
Keling tushunarli bo'lishi uchun Avto klassiga obyektlarni solishtirish uchun metod yozamiz. Deylik, biz obyektlarni narhi bo'yicha solishtirmoqchimiz, unda klassimizga quyidagi metodlarni qo'shamiz (klassni to'liq yozmadik, faqat qo'shilgan metodlarni keltiramiz):
Kodimizga e'tibor qilsangiz biz tenglik (__eq__
) yoki kichiklikni (__lt__
) tekshirmoqchi bo'lganimizda ikki avtoning aynan narhi bo'yicha solishtiramiz (self.narh == boshqa_avto.narh
).
Mana endi avtolarni solishtirsak bo'ladi:
Natija: False
Natija: True
OBYEKT UZUNLIGI
Pythonda len()
funksiyasi yordamida turli obyektlarning uzunligini bilishimiz mumkin, misol uchun matn, ro'yxat, lug'at, set va hokazo.
Natija: 11
Natija: 4
Biz len() funksiyasiga murojat qilganimizda, Python funksiyaga uzatilgan obyektning ichidagi maxsus __len__
metodiga murojat qiladi. Agar bu metod mavjud bo'lmasa dasturimiz xato qaytaradi.
Natija: TypeError: object of type 'Avto' has no len()
Misol uchun, bizning Avto klassimizda bu metod yozilmagan, shuning uchun Python TypeError xatosini qaytardi.
Kelin endi __len__
metodini qanday ishlatishga ham misol ko'raylik.
Boshlanishiga, yangi, AvtoSalon
degan klass yaratamiz. Bu klassimiz 2 ta xususiyatga ega: salon nomi (name
) va salondagi mashinalar (avtolar
).
Yuqoridagi klassdan yangi obyekt yaratamiz:
Natija: MaxAvto avtosaloni
AvtoSalon
klassimizga __repr__
metodini qo'shganimiz uchun natijamiz chiroyli ko'rinishda chiqdi.
Keling endi salonga avtomobil qo'shish uchun yangi add_avto()
metodini yozamiz. Bu metodimiz Avto klassiga oid obyektlarni qabul qilishi kerak. add_avto()
ga uaztilgan parametr Avto klassiga tegishli yoki yo'qligini tekshirish uchun maxsus isinstance()
funksiyasidan foydalanamiz.
Bu funksiya biror obyekt ma'lum klassga tegishli ekanligini tekshirish uchun ishlatiladi:
add_avto()
metodiga qaytamiz:
Metodimizni tekshirib ko'ramiz:
Mana navbat __len__
metodiga. Biz bu metod yordamida len()
funksiyasi salonimizdagi avtomobillar sonini qaytaradigan qilamiz. Buning uchun yuqoridagi AvtoSalon
klassiga __len__
funksiyani ham qo'shamiz va uni obyekt ichidagi avtolar ro'yxatyining uzunligini qaytaradigan qilamiz:
Mana endi bizning AvtoSalon
klassimizga oid obyektlar uchun ham len()
funksiyasini qo'llasak bo'ladi:
OBYEKT ELEMENTLARIGA MUROJAT QILISH
Ba'zi obyektlarning (matn, ro'yxat, lug'at va hokazo) elementlariga alohida murojat qilish mumkin.
Bizning salonimizda ham 3 ta avto bor, ularni ko'rish uchun yuqoridagi kabi element raqami orqali murojat qila olamizmi?
Natija: TypeError: 'AvtoSalon' object is not subscriptable
Afsuski yo'q. Ko'rib turganingizdek bizning obyektimizga bunday murojat qilib bo'lmas ekan. Obyektimizga bu xususiyatni qo'shish uchun __getitem__
metodini yozishimiz kerak.
Endi salon1
obyektimizning elementlariga murojat qilinganda __getitem__
metodi obyekt ichidagi avtolar
ro'yxatidan ko'rsatilgan element (avtomobilni) qaytaradi.
Keling obyekt elementlaridan birini o'zgartirib ko'ramiz:
Natija: TypeError: 'AvtoSalon' object does not support item assignment
Yana xatolik. Gap shundaki __getitem__
metodi o'z nomi bilan (get) element qaytaruvchi metod. Biror elementni o'zgartirish uchun esa __setitem__
metodini ham qo'shishimiz kerak. Bu metodimizga murojat qilinganda ham, yangi qiymat Avto klassiga oid ekanligini tekshirib olish maqsadga muvofiq bo'ladi:
Qaytadan elementni o'zgartirishga harakat qilib ko'ramiz:
Natija: Avto: Qizil Mazda 6
Kutilgan natija chiqdi
OPERATORLARNI QAYTA TALQIN QILISH (OVERLOADING)
Pythonda obyektlar o'rtasida turli arifmetik amallarni bajarish mumkin va bu amallar obyektning turiga qarab, Pytnon tomonidan turlicha talqin qilinadi. Masalan:
Sonlar:
Matnlar:
Ro'yxatlar:
va hokazo.
Keling, bu amallarni bizning obyektimizga ham qo'llab ko'ramiz. Boshlanishiga 2 ta avtosalon yarataylik, va har biriga alohida avtolar qo'shaylik. Ishimizni osonlashtirish uchun add_avto()
metodimizni ham istalgancha parametr qabul qilishga moslab o'zgartiramiz:
Obyektlarni yaratamiz:
Mavzuga qaytamiz. Operatorlarni qayta talqin qilish. Keling boshlanishiga ikki obyektni qo'shib ko'ramiz:
Natija: TypeError: unsupported operand type(s) for +: 'AvtoSalon' and 'AvtoSalon'
Demak, bu ikki obyektni qo'shib bo'lmas ekan. Biz obyekt egasi sifatida qo'shish operatorini o'zimiz istagancha talqin qilishimiz mumkin. Misol uchun AvtoSalon obyektiga boshqa AvtoSalon obyektini qo'shganda, yangi AvtoSalon obyektini qaytaraylik va bu yangi obyekt avvalgi ikki obyektning avtolariga ega bo'lsin.
Qo'shish operatorini qayta talqin qilish uchun AvtoSalon klassimizga __add__
metodini qo'shamiz.
Qo'shish operatorini tekshirib ko'ramiz:
Istasak, qo'shish operatori yordamida salonga yangi Avto qo'shish imkoniyatini ham yaratishimiz mumkin:
Tekshirib ko'ramiz:
Natija: [Avto: Qora GM Malibu, Avto: Oq GM Lacetti, Avto: Silver Toyota Carolla, Avto: Qora BMW X7]
Huddi shu kabi boshqa operatorlarni ham o'zingiz istalgancha talqin qilishingiz mumkin:
Operator | Metod |
Qo'shish |
|
Ayirish |
|
Ko'paytirish |
|
Daraja |
|
Bo'lish |
|
OBYEKTNI CHAQIRISH
Obyektlarni huddi funksiyalarni chaqirgandek chaqirish ham mumkin. Odatda biror funksiyaga murojat qilganda funksiya nomidan so'ng qavslar ochiladi va yopiladi. Agar funksiya argument qabul qilsa, ular qavs ichida beriladi.
Biz obyektimizga ham shunday imkoniyat qo'shishimiz mumkin. Buning uchun maxsus __call__
metodidan foydalaniladi.
PARAMETRSIZ CHAQIRISH
Misol uchun, kelign yuqoridagi AvtoSalon
klassiga oid obyektlar chaqirilganda salondagi avtomobillar ro'yxatini ko'rsatadigan qilaylik. Buning uchu AvtoSalon
klassiga quyidagi metodni qo'shamiz:
Mana endi obyekt chaqirib ko'ramiz:
Natija: [Avto: GM Malibu. 40000$,
Avto: GM Lacetti. 20000$,
Avto: Toyota Carolla. 45000$]
PARAMETR BILAN CHAQIRISH
Yuqorida salon1 ni parametrsiz chaqrishini ko'rdik. Keling endi parametr bilan chaqirishni ham yo'lga qo'yaylik. Bunda, yuborilgan parametr yangi avto obyekti bo'lsin, va bu parametr salondagi avtolar ro'yxatiga qo'shilsin. Metodimizni quyidagicha o'zgartiramiz:
Endi bizning klassimizga ham parametr bilan, ham parametrsiz chaqirish imkoniyati qo'shildi.
Natija: [Avto: GM Malibu. 40000$, Avto: GM Lacetti. 20000$, Avto: Toyota Carolla. 45000$, Avto: Mercedes-Benz E200. 80000$]
__call__
metodini qanday talqin qilish ham sizning ihtiyoringizda.
SO'NGSO'Z
Ushbu bo'limda biz maxsus metodlarning ba'zilari bilan tanishdik. Bu metodlarning qulayligi shundaki, siz ularni istalgacha talqin qilishingiz va har bir obyekt uchun mos keladigan qilib yaratishingiz mumkin. Ko'rib turganingizdek dunder metodlar obyektingizning imkoniyatlarini kengaytiradi va ularga qo'shimcha vazifalar yuklaydi.
AMALIYOT
Avvalga darslarda yaratilgan obyektlarga (
Shaxs
,Talaba
) turli dunder metodlarni qo'shishni mashq qiling.Obyekt haqida ma'lumot (
__rerp__
)Talabalarni bosqichi bo'yicha solishtirish (
__lt__
,__eg__
va hokazo)
Fan degan yangi klass yarating. Fan obyetklari tarkibida shu fanga yozilgan talabalarning ro'yxati saqlansin. Buning uchun Fanga add_student(),
__getitem__
,__setitem__
,__len__
kabi metodlarni qo'shing.Fanga qo'shish
+
operatori yordamida talaba qo'shish metodini yozingMinus (
-
) operatori yordamida fandan talaba olib tashlash metodini yozing (bunda talabaning passport raqami yoki ID raqami bo'yicha topib, olib tashlash mumkin)Fan obyektlarini chaqiriladigan qiling (masalan,
fizika()
, yokifizika(talaba1)
). Bu metodlarni o'zingiz istagandek talqin qiling.
KODLAR
GitHub
Repl.it
Last updated