37 / 59

Python Operator Overloading

Operatorlarni ortiqcha yuklash (Overloading) bilan tanishish

Bilganimizdek, + operatori ikkita sonni qo'shishi, ikkita ro'yxatni birlashtirishi yoki ikkita satrni konkatenatsiya qilishi mumkin.

Ba'zi moslashtirishlar bilan, biz + operatoridan foydalanuvchi belgilagan obyektlar bilan ham ishlashi uchun foydalanishimiz mumkin. Pythonning kontekstga qarab bir xil operatorning turli ma'noga ega bo'lishiga ruxsat beruvchi bu xususiyati operatorni ortiqcha yuklash (operator overloading) deb ataladi.

Python maxsus funksiyalari

Pythonda, nomining oldida va orqasida ikkita pastki chiziq (__) ga ega metodlar maxsus ma'noga ega. Masalan, __add__(), __len__() va h.k.

Bu maxsus metodlar muayyan xususiyatlar yoki xatti-harakatlarni amalga oshirish uchun ishlatilishi mumkin.

Keling, ikkita sonni + operatoridan foydalanish o'rniga __add__() metodi yordamida qo'shamiz.

example.py
number1 = 5

# number2 = number1 + 6 ga o'xshash
number2 = number1.__add__(6)
    
print(number2)  # 11

Integerlarda __add__() metodidan foydalanish mumkin, chunki:

  • Pythonda hamma narsa, jumladan integerlar ham, obyekt.
  • Integerlar biz foydalanishimiz mumkin bo'lgan __add__() metodiga ega.

Aslida, + operatori integer va floatlarni qo'shish uchun ichki tomondan __add__() metodini chaqiradi.

Mana Pythonda mavjud bo'lgan ba'zi maxsus funksiyalar:

FunksiyaTavsif
__init__()Obyektning atributlarini ishga tushiradi.
__str__()Obyektning satr ko'rinishini qaytaradi.
__len__()Obyektning uzunligini qaytaradi.
__add__()Ikkita obyektni qo'shadi.
__call__()Klass obyektlarini oddiy funksiya kabi chaqirish imkonini beradi.

Operatorni ortiqcha yuklashdan qanday foydalanish kerak?

Aytaylik, biz + operatoridan foydalanuvchi belgilagan ikkita obyektni qo'shish uchun foydalanmoqchimiz.

+ operatori ichki tomondan __add__() metodini chaqirgani uchun, agar biz bu metodni klassda amalga oshirsak, o'sha klassning obyektlarini + operatori bilan ishlaydigan qilishimiz mumkin.

Misol: Ikkita koordinatani qo'shish (Ortiqcha yuklashsiz)

Avval keling ikkita koordinatani qo'shuvchi dastur yozamiz (+ operatorini ortiqcha yuklashsiz).

example.py
class Point:
    def __init__(self, x = 0, y = 0):
        self.x = x
        self.y = y
    
    def add_points(self, other):
        x = self.x + other.x
        y = self.y + other.y
        return Point(x, y)
    
    
p1 = Point(1, 2)
p2 = Point(2, 3)

p3 = p1.add_points(p2)

print((p3.x, p3.y))   # Natija: (3, 5)

Yuqoridagi misolda, biz ikkita nuqtani qo'shish uchun add_points() metodini yaratdik. Bu metodni chaqirish uchun, biz p1.add_points(p2)dan foydalandik.

Keling, xuddi shu kodni ikkita nuqtani qo'shish uchun + operatoridan foydalanib yozamiz.

Misol: Ikkita koordinatani qo'shish (Ortiqcha yuklash bilan)

example.py
class Point:
    def __init__(self, x = 0, y = 0):
        self.x = x
        self.y = y
    
    def __add__(self, other):
        x = self.x + other.x
        y = self.y + other.y
        return Point(x, y)
    
    
p1 = Point(1, 2)
p2 = Point(2, 3)

# bu operator __add__() metodini chaqiradi
p3 = p1 + p2

print((p3.x, p3.y))   # Natija: (3, 5)

Bu yerda, p1 + p2 kodi __add__(self, other) metodini chaqiradi. self parametri p1ni, other parametri esa p2ni argument sifatida oladi.

Operatorlarni suiiste'mol qilmang

Yuqoridagi dasturda, biz + operatoridan ayirish uchun ham osongina foydalanishimiz mumkin edi, masalan shunday:

example.py
def __add__(self, other):
    x = self.x - other.x
    y = self.y - other.y
    return Point(x, y)

Endi yuqoridagi koddagi + operatori nuqtalarning ayirish amalini bajaradi. Garchi dastur xatosiz ishlasa-da, siz bundan mutlaqo qochishingiz kerak. Operatorni ortiqcha yuklashda biz har doim operatorlardan mos ravishda foydalanishimiz kerak.

Xuddi shunday, biz boshqa operatorlarni ham ortiqcha yuklashimiz mumkin. Amalga oshirishimiz kerak bo'lgan maxsus funksiya quyida jadvalda keltirilgan.

OperatorIfodaIchki tomondan
Qo'shishp1 + p2p1.__add__(p2)
Ayirishp1 - p2p1.__sub__(p2)
Ko'paytirishp1 * p2p1.__mul__(p2)
Darajap1 ** p2p1.__pow__(p2)
Bo'lishp1 / p2p1.__truediv__(p2)
Floor Divisionp1 // p2p1.__floordiv__(p2)
Qoldiq (modulo)p1 % p2p1.__mod__(p2)
Bitli chapga siljitishp1 << p2p1.__lshift__(p2)
Bitli o'ngga siljitishp1 >> p2p1.__rshift__(p2)
Bitli ANDp1 & p2p1.__and__(p2)
Bitli ORp1 | p2p1.__or__(p2)
Bitli XORp1 ^ p2p1.__xor__(p2)
Bitli NOT~p1p1.__invert__()

Taqqoslash operatorlarini ortiqcha yuklash

Python operatorni ortiqcha yuklashni faqat arifmetik operatorlar bilan cheklamaydi. Biz taqqoslash operatorlarini ham ortiqcha yuklashimiz mumkin.

Mana < operatorini Person klassining ikkita obyektini yoshiga qarab solishtirish uchun qanday ortiqcha yuklash mumkinligiga misol:

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

    # < operatorini ortiqcha yuklash
    def __lt__(self, other):
        return self.age < other.age

p1 = Person("Alice", 20)
p2 = Person("Bob", 30)

print(p1 < p2)  # True ni chop etadi
print(p2 < p1)  # False ni chop etadi

Natija

kod
True
False

Bu yerda, __lt__() ikkita obyektning age atributini solishtirish uchun < operatorini ortiqcha yuklaydi.

__lt__() metodi quyidagini qaytaradi:

  • True - agar birinchi obyektning yoshi ikkinchi obyektning yoshidan kichik bo'lsa
  • False - agar birinchi obyektning yoshi ikkinchi obyektning yoshidan katta bo'lsa

Xuddi shunday, boshqa taqqoslash operatorlarini ortiqcha yuklash uchun amalga oshirishimiz kerak bo'lgan maxsus funksiyalar quyida jadvalda keltirilgan.

OperatorIfodaIchki tomondan
Kichikp1 < p2p1.__lt__(p2)
Kichik yoki tengp1 <= p2p1.__le__(p2)
Tengp1 == p2p1.__eq__(p2)
Teng emasp1 != p2p1.__ne__(p2)
Kattap1 > p2p1.__gt__(p2)
Katta yoki tengp1 >= p2p1.__ge__(p2)

Operatorni ortiqcha yuklashning afzalliklari

Mana operatorni ortiqcha yuklashning ba'zi afzalliklari:

  • Tanish operatorlardan foydalanishga ruxsat berish orqali kodning o'qilishini yaxshilaydi.
  • Klass obyektlari tayyor turlar va boshqa foydalanuvchi belgilagan turlar bilan izchil xatti-harakat qilishini ta'minlaydi.
  • Ayniqsa murakkab ma'lumot turlari uchun kod yozishni osonlashtiradi.
  • Bitta operator metodini amalga oshirish va uni boshqa operatorlar uchun ishlatish orqali kodni qayta ishlatish imkonini beradi.

Ko'proq o'qing: Python Classes and Objects, Self in Python, Demystified, Precedence and Associativity of Operators in Python

QBilimingizni sinab ko'ring
1 / 3

1. Python obyektlarida + operatorini o'z klassingiz uchun ortiqcha yuklash uchun qaysi maxsus metodni amalga oshirish kerak?