Відповіді:
Слідкуйте далі ...:
>>> 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