"Mro ()" ne yapar?


Yanıtlar:


211

Takip etmek...:

>>> class A(object): pass
... 
>>> A.__mro__
(<class '__main__.A'>, <type 'object'>)
>>> class B(A): pass
... 
>>> B.__mro__
(<class '__main__.B'>, <class '__main__.A'>, <type 'object'>)
>>> class C(A): pass
... 
>>> C.__mro__
(<class '__main__.C'>, <class '__main__.A'>, <type 'object'>)
>>> 

Tek bir kalıtıma sahip olduğumuz sürece __mro__, sadece şunlardan oluşur: sınıf, tabanı, tabanının tabanı vb.object (Elbette sadece yeni tarz sınıflar için çalışır).

Şimdi, çoklu kalıtımla ...:

>>> class D(B, C): pass
... 
>>> D.__mro__
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>)

... aynı zamanda, içinde __mro__hiçbir sınıfın çoğaltılmadığına ve atalarından sonra hiçbir sınıfın gelmediğine dair güvenceye sahip olursunuz , ancak ilk olarak aynı çoklu miras düzeyine giren sınıflar (bu örnekte B ve C gibi) __mro__soldan sağa.

Bir sınıfın örneğinde elde ettiğiniz her öznitelik, sadece yöntemler değil, kavramsal olarak araştırılır __mro__, bu nedenle, atalar arasında birden fazla sınıf bu adı tanımlarsa, bu size özniteliğin nerede bulunacağını söyler - ilk sınıfta __mro__bu ismi tanımlayan.


9
merhaba, alex, D .__ mro__ ve D.mro () arasında herhangi bir fark var mı?
zjm1126

26
mrobir meta sınıf tarafından özelleştirilebilir, sınıf başlatmada bir kez çağrılır ve sonuç, içinde saklanır __mro__- bkz. docs.python.org/library/… .
Alex Martelli

23
Neden öznitelik çözümleme sırası yerine yöntem çözümleme sırası deniyor ?
Bentley4

1
Sadece @Alex Martelli söyledi ve içeriği gibi python-history.blogspot.com/2010/06/... , MRO yeni sınıf yalnızca, kullanıldığında özellik eklenti olması gerekirken Python 2.2 MRO ve Python 2.3 MRO (C3) kullanılmış.
andy

82

mro()Metot Çözüm Sırası anlamına gelir. Yöntemler için arandıkları sırayla, sınıfın türetildiği türlerin bir listesini döndürür.

mro () veya __mro__ yalnızca yeni stil sınıflarında çalışır. Python 3'te sorunsuz çalışırlar. Ancak python 2'de bu sınıfların miras alması gerekir object.


10

Bu belki de çözüm sırasını gösterir.

class A(object):
    def dothis(self):
        print('I am from A class')

class B(A):
    pass

class C(object):
    def dothis(self):
        print('I am from C class')

class D(B, C):
    pass

d_instance= D()
d_instance.dothis()
print(D.mro())

ve cevap olurdu

I am from A class
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.A'>, <class '__main__.C'>, <class 'object'>]

Kural derinliktir, bu durumda D, B, A, C anlamına gelir.

Python normalde, miras alan sınıfları ararken derinlik sıralaması kullanır, ancak iki sınıf aynı sınıftan miras aldığında, Python bu sınıfın ilk sözünü mro'dan kaldırır.


1
Gördüğünüz gibi sıra D, B, A, C
Stryker

1
"Python, bu sınıfın ilk sözünü mro'dan kaldırır" derken neyi kastediyorsunuz?
Ruthvik Vaila

2
@RuthvikVaila: Bence bu kısım çok az ifade edilmiş. Python'un tarihi hakkındaki bu blog gönderisinde Guido van Rossum (Python 2.2'de tanıtılan MRO şeması hakkında) "Bu aramada herhangi bir sınıf kopyalanırsa, son oluşum hariç tümü MRO listesinden silinir" (vurgu benim ). Bu, sınıfın ilk "bahsedilmesinden" daha fazlasını kaldırabileceği anlamına gelir.
martineau

1

Elmas mirasında çözümlenme sırası farklı olacaktır.

class A(object):
    def dothis(self):
        print('I am from A class')


class B1(A):
    def dothis(self):
        print('I am from B1 class')
    # pass


class B2(object):
    def dothis(self):
        print('I am from B2 class')
    # pass


class B3(A):
    def dothis(self):
        print('I am from B3 class')


# Diamond inheritance
class D1(B1, B3):
    pass


class D2(B1, B2):
    pass


d1_instance = D1()
d1_instance.dothis()
# I am from B1 class
print(D1.__mro__)
# (<class '__main__.D1'>, <class '__main__.B1'>, <class '__main__.B3'>, <class '__main__.A'>, <class 'object'>)


d2_instance = D2()
d2_instance.dothis()
# I am from B1 class
print(D2.__mro__)
# (<class '__main__.D2'>, <class '__main__.B1'>, <class '__main__.A'>, <class '__main__.B2'>, <class 'object'>)

ama çözünürlük neden farklı?
Vadim

Çoklu miras senaryosunda, belirtilen herhangi bir öznitelik ilk önce geçerli sınıfta aranır. Bulunmazsa, arama aynı sınıfta iki kez arama yapmadan önce derinlemesine, sol-sağ tarzında üst sınıflara devam eder.
Girish Gupta

üzgünüm ama neden ilk durumda gittiğini anlamıyorum class B3ama ikinci durumda class Asonra gidiyorclass B1
Vadim
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.