Method Resolution Order (MRO) — Python'da bir sınıfın metodlarını ve özniteliklerini ararken hangi sırayla sınıfların gözden geçirileceğini belirleyen bir mekanizmadır, çoklu miras durumunda.
C3 lineerleştirme (C3 linearization) — metod çözümleme sırasını oluşturmak için kullanılan bir algoritmadır. MRO'yu anlamak, karmaşık sınıf hiyerarşileri tasarlarken kritik öneme sahiptir, böylece belirsizlikler ve beklenmedik davranışlardan kaçınılabilir.
Herhangi bir sınıfın MRO'sunu __mro__ niteliği veya mro() fonksiyonu ile öğrenebilirsiniz:
class A: def hello(self): print('A') class B(A): def hello(self): print('B') class C(A): def hello(self): print('C') class D(B, C): pass print(D.__mro__) # (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>) obj = D() obj.hello() # 'B', çünkü B, MRO'da C'den önce gelir.
MRO'yu açıkça değiştirmek mümkün değildir, ancak temel sınıfların sırasını kontrol edebilirsiniz.
Bir sınıf birden fazla anne babadan miras alıyorsa metodlar hangi sırayla çağrılacak? Örneğin:
class Base: def foo(self): print('Base') class Left(Base): def foo(self): print('Left') super().foo() class Right(Base): def foo(self): print('Right') super().foo() class Child(Left, Right): pass Child().foo()
Birçok kişi "foo"'nun önce Left'den, sonra Right'tan, en son Base'den çağrılacağını bekler — ve öyle olur. Ancak eğer temel sınıfların sırasını değiştirirseniz (class Child(Right, Left)), sıra değişecektir!
Doğru Cevap:
Çağrı sırası, MRO'da tanımlandığı gibi olacaktır. İlk durumda — Left, Right, Base. MRO belirli bir algoritmaya göre oluşturulur (C3 lineerleştirme):
[Child, Left, Right, Base, object]
Hikaye
Birden fazla miras mantığı, metodun ezilmesi
Geliştirici ekibi, karışıma yönelik çoklu miras kullandı. Yanlış temel sınıf sırası nedeniyle, karışımın ortak mantığı alt sınıf tarafından "ezildi" ve bazı iş mantıkları yerine getirilmedi, bu da veri kaybına yol açtı.
Hikaye
Yanlış ana metod çağrılıyor
Sonlandırıcı metodda (__del__), temel sınıfın metodunun çağrılacağı bekleniyordu. Ancak, MRO'yu yanlış anlama nedeniyle, kaynak temizliği yapmayan başka bir miras alınan metod çağrıldı. Sonuç olarak, bellek sızıntısı oldu.
Hikaye
Çağrı zincirini anlamadan super() kullanımı
Python 3 projesinde, müşteri çoklu miras içeren kodun bir kısmını yeniden yazdı ve super() aracılığıyla çağrıları güncellemeyi unuttu. Bu, metodun sürekli kendisini çağırmasına neden olan sonsuz rekürsiyon durumlarına yol açtı, çünkü metod çözümleme sırası hatalıydı.