В вашем конкретном примере после поиска B
мы не можем сразу рассмотреть Y
, потому что это дочерний элемент A
. Мы не можем рассматривать Z
сразу, потому что M
наследуется от A
до наследования от Z
.
Python использует порядок разрешения методов C3 подробности здесь .
Порядок разрешения C3 хорошо решает проблему наследования алмазов
В приведенном ниже примере у нас есть очень общий класс Object
, который является суперклассом B
и C
. Мы хотим, чтобы реализации методов (скажем, __repr__
или что-то в этом роде) в Object
рассматривались только в том случае, если ни B
, ни C
не имеют реализации.
Object
/ \
B C
\ /
A
Другими словами, каждый возможный родитель в транзитивном замыкании родительских классов A
рассматривается, но классы упорядочены в соответствии с "самым последним" путем от базового класса к рассматриваемому классу.
Есть два пути к object
:
A -> B -> Object
A -> C -> Object
«Последний» путь — A -> C -> Object
, потому что A -> B -> Object
будет раньше в левостороннем поиске в глубину.
Линеаризация C3 удовлетворяет двум ключевым инвариантам:
- если
X
наследуется от Y
, X
проверяется перед Y
.
- если
Z
наследуется от U
, а затем V
в таком порядке, U
проверяется перед V
.
Действительно, C3
линеаризация гарантирует выполнение обоих этих свойств.
Можно создавать иерархии, которые нельзя линеаризовать, и в этом случае вы получите исключение во время определения класса.
работает inherit.py
class E: pass
class F: pass
class A(E, F): pass
class B(F, E): pass
class Z(A, B): pass
выдает следующую ошибку.
Traceback (most recent call last):
File "inherit.py", line 5, in <module>
class Z(A, B): pass
TypeError: Cannot create a consistent method resolution
order (MRO) for bases E, F
person
Gregory Nisbet
schedule
15.04.2019