CodeGym /Kurslar /Python SELF AZ /Operatorların aşırı yüklənməsi

Operatorların aşırı yüklənməsi

Python SELF AZ
Səviyyə , Dərs
Mövcuddur

6.1 Sehrli metodlar

Python-da operatorların overloading-i, daxili operatorların (məsələn, +, -, *, /) davranışını istifadəçi sinifləri üçün təyin etməyə və ya dəyişdirməyə imkan verir. Bu, xüsusi metodlar vasitəsilə həyata keçirilir və həmin metodlara sehrli metodlar deyilir.

Məsələn, öz sinfinizdə müqayisə operatorlarını overload edə bilərsiniz:

Operator Alt xəttsiz metod Metodun imzası
== eq() __eq__(self, other)
!= ne() __ne__(self, other)
< lt() __lt__(self, other)
<= le() __le__(self, other)
> gt() __gt__(self, other)
>= ge() __ge__(self, other)

Tutaq ki, siz öz sinfinizi yazmısınız və istəyirsiniz ki, həmin sinfin obyektləri sizin istədiyiniz şəkildə müqayisə edilsin. Bunun üçün sadəcə sinfinizdə «__eq__» metodunu implement etməlisiniz, və Python hər dəfə sizin sinif obyektlərinizi müqayisə edərkən həmin metodu çağıracaq.

Nümunə:


class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        
    def __eq__(self, other):
        return self.x == other.x and self.y == other.y
        
# İstifadə
v1 = Vector(2, 3)
v2 = Vector(2, 3)
v3 = Vector(4, 5)
print(v1 == v2)  # Çap edəcək: True
print(v1 == v3)  # Çap edəcək: False

Hər dəfə obyektlərinizi müqayisə edərkən Python yoxlayır ki, onların «__eq__» funksiyası implement edilibmi. Əgər varsa, onu çağırır. Yoxdursa, onda sadəcə obyektlərin referanslarını müqayisə edir.

Əslində yuxarıdakı nümunədə yazılan belədir (amma metodu yoxlamağı da əlavə etmək lazımdır):


# İstifadə
v1 = Vector(2, 3)
v2 = Vector(2, 3)
v3 = Vector(4, 5)
print(v1.__eq__(v2))  # Çap edəcək: True
print(v1.__eq__(v3))  # Çap edəcək: False

6.2 Bütün operatorların siyahısı

Ümumilikdə yenidən yükləmə üçün 6 operator qrup mövcuddur.

Riyazi operatorlar:

Operator Altdan xətsiz metod Metodun imzası
+ add __add__(self, other)
- sub __sub__(self, other)
* mul __mul__(self, other)
/ truediv __truediv__(self, other)
// floordiv __floordiv__(self, other)
% mod __mod__(self, other)
** pow __pow__(self, other)

Müqayisə operatorları:

Operator Altdan xətsiz metod Metodun imzası
== eq __eq__(self, other)
!= ne __ne__(self, other)
< lt __lt__(self, other)
<= le __le__(self, other)
> gt __gt__(self, other)
>= ge __ge__(self, other)

Məntiqi operatorlar:

Operator Altdan xətsiz metod Metodun imzası
& and __and__(self, other)
| or __or__(self, other)
^ xor __xor__(self, other)
~ invert __invert__(self)

İndeksasiya və dilim operatorları:

Operator Metod
obj[key] __getitem__(self, key)
obj[key] = value __setitem__(self, key, value)
del obj[key] __delitem__(self, key)

Unar operatorlar:

Operator Metod
- __neg__(self)
+ __pos__(self)
abs() __abs__(self)
~ __invert__(self)

Təyinetmə operatorları:

Operator Metod
+= __iadd__(self, other)
-= __isub__(self, other)
*= __imul__(self, other)
/= __itruediv__(self, other)
//= __ifloordiv__(self, other)
%= __imod__(self, other)
**= __ipow__(self, other)

Ola bilsin ki, buna görə Python bu qədər yavaşdır – hər dəfə operatorun icrasından əvvəl o, sinifdə və onun bütün ana siniflərində uyğun funksiyanı axtarır. Amma bunun sayəsində dünyada ən yığcam kodu yazmaq mümkündür :)

6.3 İndeksləmə Operatoru

Obyektlərin müqayisə edilməsi və ya çoxluqların çıxarılması məsələləri müəyyən mənada aydındır. Əgər məntiqi və ya riyazi əməliyyatların tətbiq olunduğu bir sinif yazdıqda bunu özünüz də başa düşəcəksiniz.

Sizə maraqlı bir nümunədən danışmaq istəyirəm – yəni indeksləmə operatoru. Gəlin dərhal nümunə koduna baxaq:


class CustomList:
    def __init__(self, data):
        self.data = data
        
    def __getitem__(self, index):
        return self.data[index]
        
    def __setitem__(self, index, value):
        self.data[index] = value
        
    def __delitem__(self, index):
        del self.data[index]
        
    def __repr__(self):
        return repr(self.data)
        
# İstifadə
c_list = CustomList([1, 2, 3, 4, 5])
print(c_list[1])  # Çıxış: 2
c_list[1] = 10
print(c_list)  # Çıxış: [1, 10, 3, 4, 5]
del c_list[1]
print(c_list)  # Çıxış: [1, 3, 4, 5]

Burada üç əməliyyatın nümunəsini görürük:

  • Məlumatların indeks vasitəsilə oxunması
  • Məlumatların indeks vasitəsilə yazılması
  • Hətta məlumatların indeks vasitəsilə silinməsi

Amma məlumatların içəridə siyahı formasında saxlanılması vacib deyil. Və ya indeks mütləq rəqəm olmaq məcburiyyətində deyil. Məsələn, dictionary (sözlük) sinifi bu cür reallaşdırılıb.

SuperList Yaradaq

list sinifini xatırlayırsınız? Ona ancaq mövcud indekslərə elementlər təyin etmək mümkündür. Gəlin öz sinifimizi yaradaq, ona SuperList adını verək; bu sinifin elementlərinə istənilən indekslə müraciət etmək mümkün olacaq:

  • Əgər indeks < 0-dırsa, elementi əvvələ yerləşdirəcəyik
  • Əgər indeks >= len-dirsə, elementi sona əlavə edəcəyik
  • Qalan hallarda sadəcə elementi qaytaracağıq

Nümunə:


class SuperList(list):
    def __init__(self, value):
        super().__init__(value)
        
    def __setitem__(self, index, value):
        if index >= len(self):
            super().append(value)
        elif index < 0:
            super().insert(0, value)
        else:
            super().__setitem__(index, value)
        
lst = SuperList([1, 2, 3])
lst[200] = 100
lst[-200] = 99
print(lst)  # [99, 1, 2, 3, 100]

Beləliklə, indekslərin yenidən yüklənməsi əla bir funksionallıqdır və praktiki istifadəsini şiddətlə tövsiyə edirəm. Bu günlük bu qədər.

Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION