ProgramlamaBackend Geliştirici

Python'da sınıf mirası durumunda öznitelik arama sıralaması mekanizması (MRO - Method Resolution Order) nasıl çalışır? Metodların çözümleme sırasını anlamanın önemi nedir ve bunu nasıl öğrenebilir/değiştirebiliriz?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap

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.

Aldatıcı Soru

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]

Bilinmeyen detaylar nedeniyle yapılan gerçek hata örnekleri


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ı.