Pythonda dunder metodlar


Pythonda class lar bilan ishlashni uqlaylashtirish uchun Python bizga dunder method(double underscore)larni taqdim qiladi. Bu methodlar ikki tagchizi(__) bilan yoziladigan methodlar hisoblanadi. Bu methodlar klass obyektlari bilan ishlashni yana ham qulaylashtiradi. Menimcha eng ko'p foydalanilgan dunder methodlardan biri bu init bo'lsa kerak bu method klass attributlarini belgilab berish uchun xizmat qiladi.

Quyidagi misolda __init__ bilan tushunushga harakat qilib ko'ramiz.

class Person:
  def __init__(self, name):
    self.name = name

p = Person("Farrux")
print(p)

Natija:

<__main__.Person object at 0x79cc36c9a920>

Yuqoridagi misolda __init__ dunder methodi sinfga berilgan qiymatni qabul qilib oldi va name o'zgaruvchisiga tayinladi va print bizga Person sinfining xotira manzilini chop qilib berdi. Lekin bu ma'lumot tushunarsiz. Chop qilishni tushunarliroq qilishimiz ham mumkin bu bizga ishlab chiqayotgan dasturimizni debug qilish jarayonini oson va tushunarli bo'lishiga yordam beradi. Demak maqsadni aniqlab oldik bizga debug qilish oson va qulay bo'lishi uchun Person sinfiga qo'shimcha kiritishimiz kerak bo'ladi. Sinfimiz uchun __repr__ dunder methodidan foydalanamiz. Bu method sinf obyektni chop qilinganda birinchi bo'lib ishga tushadi va methodda yozilgan mantiqiy amallarni bajaradi.

class Person:
  def __init__(self, name):
    self.name = name

  def __repr__(self):
    return f"Person(name={self.name})"

p = Person("Farrux")
print(p)

Natija:

Person(name=Farrux)

Xo'sh bu yerda nima sodir bo'ldi? Biz print bilan sinf obyektiga murojaat qilganimizda Python obyekt ichidan __repr__ ni qidiradi va __repr__ da yozligan mantiqni chop qiladi.

Endi menimcha hamma uchun tushunarli ko'rinishga o'tdi. __repr__ ichida siz o'zingizni talablaringizqa qarab mantiqiy amallarni yozishingiz mumkin.

Yaxshiroq tushunish uchun yana bir misol ko'ramiz. Aytaylik bizda shunday sinf bor bu sinf ismlar ro'yxatini o'zida saqlasin.

class Names:
  def __init__(self):
    self.names = []

  def add(self, name):
    self.names.append(name)

  def __repr__(self):
    return f'{self.names}'

names = Names()
names.add("Farrux")
names.add("Sanjar")
names.add("Sardor")
names.add("Sherzod")

print(names)

Natija:

['Farrux', 'Sanjar', 'Sardor', 'Sherzod']

Yuqoridagi misolimizda yangi ism qo'shimoqchi bo'lsak add methodidan foydalanishimiz kerak bo'ladi. Xo'sh bu ishni oddiy + amali bilan qilsak bo'lmaydimi? miso uchun names + "Toshmat"? Albatta bo'ladi! Buning uchun bizga Pythonning __add__ dunder methodi kerak bo'ladi.

class Names:
  def __init__(self):
    self.names = []

  def add(self, name):
    self.names.append(name)

  def __repr__(self):
    return f'{self.names}'

  def __add__(self, name):
    self.names.append(name)
    return self

names = Names()
names.add("Farrux")
names.add("Sanjar")
names.add("Sardor")
names.add("Sherzod")

names + "Toshmat"

print(names)

Natija:

['Farrux', 'Sanjar', 'Sardor', 'Sherzod', 'Toshmat']

Menimcha dunder methodlar nima uchun kerak bo'lishi haqida umumiy tushunchaga ega bo'ldingiz. Endi esa boshqa methodlarni ham ko'rib chiqamiz.

Misollar

Ro'yxatdan o'chirish

class Names:
  def __init__(self):
    self.names = []

  def add(self, name):
    self.names.append(name)

  def __repr__(self):
    return f'{self.names}'

  def __add__(self, name):
    self.names.append(name)
    return self

  def __sub__(self, name):
    if name in self.names:
       self.names.remove(name)
    return self

names = Names()
names.add("Farrux")
names.add("Sanjar")
names.add("Sardor")
names.add("Sherzod")

names + "Toshmat"
names - "Sardor"

print(names)

Natija:

['Farrux', 'Sanjar', 'Sherzod', 'Toshmat']

Bu yerda Sardor ismi ro'yxatdan o'chirildi.

Sinf obyektlarini taqqoslash operaorlari(dunder methodlar).

Method Operator
x.__lt__(self, y) x < y
x.__le__(self, y) x <= y
x.__gt__(self, y) x > y
x.__ge__(self, y) x >= y
x.__eq__(self, y) x == y
x.__ne__(self, y) x != y

Jadvaldagi methodlarni tushunish uchun hayotiy masala bilan o'rganishimiz kerak bu yaxshi tushunishimizga yordam beradi. Aytaylik ikkita xodimni oylik ish haqqini solishtirish kerak bo'lsin. Xodim haqidagi ma'lumotlarni Xodim degan sinf o'zida saqlasin.

class Xodim:
  def __init__(self, full_name, age, salary):
    self.full_name = full_name
    self.age = age
    self.salary = salary

  def __repr__(self):
    return f"ISM: {self.full_name}, YOSH: {self.age}, MAOSH: {self.salary} so'm"

  def __gt__(self, xodim_maoshi):
    return self.salary > xodim_maoshi.salary

xodim1 = Xodim("Farrux Elomonov", 27, 5000000)
xodim2 = Xodim("Elbek Alloyorov", 30, 7000000)

print(xodim1 < xodim2)

Bu yerda xodim1 obyekti(instance) __gt__ methodida self bo'lib kelyapdi. Ya'ni slef.salary bu xodim1.salary degani, xodim2 buning aksi.

Hozircha o'zim tushunganlarimni post ko'rinishida yozib chiqdim, agar xato kamchiliklar bo'lsa [email protected] manzliga yuborishingizni iltimos qilib qolardim. Vaqt o'tishi bilan o'zgartirish va qo'shimchalar qo'shilishi mumkin.


© 2024 Farrux Elomonov