Python da polimorfizmga erishishning maxsus usuli bor — duck typing. Bu inglizcha maqoldan olingan: "If it walks like a duck and quacks like a duck, it's a duck" — ya'ni "Agar o'rdakday yursa va o'rdakday ovoz chiqarsa, demak u o'rdak."
Python da bu shuni anglatadi: biror obyektda kerakli metod mavjud bo'lsa, u qaysi klassdan ekanligi muhim emas — ishlatish mumkin. Meros shart emas!
class It:
def tovush(self):
return "Vov-vov!"
class Mushuk:
def tovush(self):
return "Miyov!"
class Qush:
def tovush(self):
return "Chiv-chiv!"
# Meros yo'q — ammo hammasi tovush() metodiga ega!
hayvonlar = [It(), Mushuk(), Qush()]
for h in hayvonlar:
print(h.tovush())Chiqish:
Vov-vov!
Miyov!
Chiv-chiv!It, Mushuk, Qush klasslar bir-biridan meros olmagan. Ammo hammasi tovush() metodiga ega — shu yetarli! Python har qanday tur tekshirmaydi, faqat metodning bor-yo'qligini ko'radi.
Bu oddiy meros yondashuvidan farqli:
# Duck typing bilan funksiya — tur muhim emas
def barcha_tovush(hayvonlar_royxati):
for hayvon in hayvonlar_royxati:
print(hayvon.tovush()) # qaysi klass ekanligini bilmaymiz
# Hech qaysi klass meros olmagan — lekin hammasi ishlaydi!
barcha_tovush([It(), Qush(), Mushuk(), It()])Endi boshqa misol — chop etish qurilmalari:
class Printer:
def chiqar(self, matn):
return f"Printer: {matn}"
class Ekran:
def chiqar(self, matn):
return f"Ekran: {matn}"
class Fayl:
def chiqar(self, matn):
return f"Fayl: {matn}"
# Bu funksiya har qanday qurilma bilan ishlaydi
def xabar_yuborish(qurilma, matn):
return qurilma.chiqar(matn)
p = Printer()
e = Ekran()
f = Fayl()
print(xabar_yuborish(p, "Salom")) # Printer: Salom
print(xabar_yuborish(e, "Dunyo")) # Ekran: Dunyo
print(xabar_yuborish(f, "Python")) # Fayl: Pythonxabar_yuborish funksiyasi qurilma ning turi nima ekanini bilmaydi. U faqat chiqar() metodining borligini kutadi. Bu — duck typing!
Muhim qoidalar:
inheritance) shart emas — to'g'ri metod bo'lsa yetarliQurilmalar uchun duck typing
Uchta mustaqil klass va bitta funksiya yarating:
Printer klassini yarating: chiqar(self, matn) metodi "Printer: {matn}" qaytarsinEkran klassini yarating: chiqar(self, matn) metodi "Ekran: {matn}" qaytarsinFayl klassini yarating: chiqar(self, matn) metodi "Fayl: {matn}" qaytarsinxabar_yuborish(qurilma, matn) funksiyasini yarating — u qurilma.chiqar(matn) natijasini qaytarsinMisol:
Kiritish:
printer
SalomChiqish:
Printer: Salom