Ответы:
Следуйте ...:
>>> 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'>)
>>>
Пока у нас есть единичное наследование, __mro__
это просто кортеж из: класса, его базы, его базы и т. Д. object
(Работает, конечно, только для классов нового стиля).
Теперь с множественным наследованием ...:
>>> class D(B, C): pass
...
>>> D.__mro__
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>)
... вы также получаете уверенность в том, что __mro__
ни один класс не дублируется и ни один класс не идет после своих предков, за исключением тех классов, которые сначала входят на одном уровне множественного наследования (например, B и C в этом примере), находятся в __mro__
слева направо.
Каждый атрибут, который вы получаете в экземпляре класса, а не только методы, концептуально просматривается вдоль __mro__
, поэтому, если более одного класса среди предков определяют это имя, это сообщает вам, где будет найден атрибут - в первом классе в то, __mro__
что определяет это имя.
mro
может быть настроен с помощью метакласса, вызывается один раз при инициализации класса, а результат сохраняется в __mro__
- см. docs.python.org/library/… .
mro()
означает Порядок разрешения методов. Он возвращает список типов, производных от класса, в порядке их поиска для методов.
mro () или __mro__ работает только с новыми классами стилей. В python 3 они работают без проблем. Но в Python 2 эти классы должны наследовать от object
.
Возможно, это покажет порядок разрешения.
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())
и ответ будет
I am from A class
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.A'>, <class '__main__.C'>, <class 'object'>]
Правило - сначала глубина, что в данном случае будет означать D, B, A, C.
Python обычно использует порядок глубины при поиске наследующих классов, но когда два класса наследуются от одного и того же класса, Python удаляет первое упоминание этого класса из mro.
Порядок разрешения будет другим в наследовании алмазов.
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'>)
class B3
а во втором случае идет class A
послеclass B1