11.1 Method Resolution Order
Metodların həlli sırası (Method Resolution Order, MRO) Python-un metod və atributları siniflər iyerarxiyasında hansı ardıcıllıqla axtardığını müəyyən edir. Bu, xüsusilə bir neçə ana sinifdən atribut və metodları miras alan zaman, çoxəsaslı miras ilə işləyərkən vacibdir.
Bundan qısa desək, Python siniflərin irs ağacını dolaşması üçün sərt, sabit bir ardıcıllıq (və ya, daha doğru desək, alqoritm) mövcuddur. Bu alqoritm metodların düzgün axtarış ardıcıllığını təmin edir və bu şəkildə təsvir edilə bilər:
C3-Lineyarizasiya Alqoritmi
C3-lineyarizasiya alqoritmi MRO-nu aşağıdakıları birləşdirərək müəyyən edir:
- Ən əsas sinif.
- Valideyn siniflərinin ardıcıl qaydada siyahısı.
- Həmin ardıcıllıqda valideyn siniflərinin MRO-su.
C3-Lineyarizasiya Alqoritminin Qaydaları
- Metodların lokal ardıcıllığını qorumaq: əgər
A
sinfiB
sinfindən əvvəl qeyd olunubsa,A
sinfinin bütün metodlarıB
sinfinin metodlarından əvvəl nəzərdən keçirilməlidir. - Valideyn siniflərində ardıcıllığı qorumaq: əgər
A
sinfiB
sinfinin valideynidirsə,A
sinfinin bütün metodlarıB
sinfinin metodlarından əvvəl nəzərdən keçirilməlidir. - Miras ardıcıllığını nəzərə almaq: əgər
C
sinfi bir neçə və ya daha çox sinfin valideyni olarsa,C
sinfinin metodlarının ardıcıllığı həmin siniflərin hamısının MRO-sunda qorunmalıdır.
Alqoritmin addımları:
Addım 1. Ən əsas sinifdən başlayırıq:
Həmişə metod çağırılan sinifdən başlayırıq.
Addım 2. Əsas sinifləri ardıcıllıqla əlavə edirik:
Mövcud sinifdən sonra, irsiyyət zamanı göstərilən ardıcıllıqla əsas sinifləri yoxlayırıq.
Addım 3. Valideyn siniflərini dolaşırıq:
Orada sahələri və metodları axtarırıq.
Addım 4. Valideyn siniflərinin MRO-sunu birləşdiririk:
Əgər eyni əsas sinif bir neçə yol ilə miras alınırsa, o yalnız bir dəfə və düzgün ardıcıllıqla yoxlanılır (bütün digər hallarda o ötürüləcək).
«Alqoritmlar və verilənlər strukturları» mövzusu ilə artıq tanış olanlar üçün, bu, genişlik yox, dərinlik üzərində axtarışdır.
11.2 MRO ilə tanışlıq
Python-da metodların və sinif sahələrinin yoxlanma ardıcıllığını __mro__
atributu və ya mro()
funksiyası ilə yoxlamaq olar.
Nümunə:
class A:
def method(self):
print("A")
class B(A):
def method(self):
print("B")
class C(A):
def method(self):
print("C")
class D(B, C):
def method(self):
print("D")
# MRO-nu yoxlamaq
print(D.__mro__)
Nəticə belə olacaq:
(<class '__main__.D'>,
<class '__main__.B'>,
<class '__main__.C'>,
<class '__main__.A'>,
<class 'object'>)
Bu, Python-un metodları və atributları axtarma ardıcıllığını göstərir:
D
: Python əvvəlcə metoduD
sinifində yoxlayır.-
B
: Daha sonra Python metoduB
sinifində (ilk valideyn sinif) yoxlayır. -
C
: Əgər metodB
sinfində tapılmasa, Python metoduC
sinifində (ikinci valideyn sinif) yoxlayır. -
A
: Əgər metodB
vəC
siniflərində tapılmasa, Python metoduA
sinifində yoxlayır. -
object
: Sonda, Python metodu əsasobject
sinifində yoxlayır.
11.3 super()
-dən MRO ilə istifadə
super()
funksiyası metodları düzgün ardıcıllıqla parent class-ların çağırılmasına yönəldilir.
super()
-dən istifadə nümunəsini nəzərdən keçirək:
class A:
def method(self):
print("A")
super().method()
class B(A):
def method(self):
print("B")
super().method()
class C(A):
def method(self):
print("C")
super().method()
class D(B, C):
def method(self):
print("D")
super().method()
d = D()
d.method()
Nəticə aşağıdakı kimi olacaq:
D
B
C
A
Ardıcıllığın sırası (MRO)
1. method
metodunun D
class-ında çağırılması:
- Python əvvəlcə
D
class-ında metod axtarır və onu tapır. D.method()
metodu icra edilir və"D"
çap olunur.- Daha sonra
super().method()
çağırılır və bu, növbəti metodun çağırılması üçün MRO-ya yönəldilir.
2. method
metodunun B
class-ında çağırılması:
- MRO-ya əsasən,
D
-dən sonra növbəti classB
-dir. B.method()
metodu icra edilir və"B"
çap olunur.- Daha sonra
super().method()
çağırılır və bu, növbəti metodun çağırılması üçün MRO-ya yönəldilir.
3. method
metodunun C
class-ında çağırılması:
- MRO-ya uyğun olaraq,
B
-dən sonra növbəti classC
-dir. C.method()
metodu icra edilir və"C"
çap olunur.- Daha sonra
super().method()
çağırılır və bu, növbəti metodun çağırılması üçün MRO-ya yönəldilir.
4. method
metodunun A
class-ında çağırılması:
- MRO-ya əsasən,
C
-dən sonra növbəti classA
-dir. A.method()
metodu icra edilir və"A"
çap olunur.- Daha sonra
super().method()
çağırılır, ammaA
-nın parent class-larında metod olmadığından (istisnaobject
), çağırış heç bir hərəkətlə nəticələnmir.
GO TO FULL VERSION