tl; dr: потому что B.__init__
- это то, что должно было вызвать C.__init__
через super(B, self).__init__()
, и вы обошли этот вызов.
Почему C .__ init __ ()не напечатано?
Потому что ты не сказал этого.Множественное наследование включает сотрудничество, и вы использовали явные ссылки на классы, отрицая это сотрудничество.
Если бы вы заменили все "супер-подобные" вызовы на super().__init__()
(так как вы пометили его как Python 3), вывы увидите вывод вида:
A.__init__()
C.__init__()
B.__init__()
D.__init__()
Фактически, вы увидите этот вывод, если вы просто изменили просто «супер-подобный» вызов B
на:
super(B, self).__init__()
super().__init__()
Так почему А не вызвал С в вашем случае?
Было бы излишним копировать хорошо изложенные ответы в другом месте на сайте о MRO.
ПочемуC .__ init __ () печатается, если я ставлю super () .__ init __ () вместо A .__ init __ (self)?
Поскольку супер-аргумент без аргументов идет слева направо , поэтому сначала просматривается B
, а затем внутри B вы используете явную ссылку на класс (A.__init__(self)
).И при этом вы теряете весь (самый *) контекст, который D также имел в качестве суперкласса C
.
super()
- это то, что помогает вам ориентироваться в MRO, и привело бы вас к C.__init__()
, если бы вы позволили.Но в B
вы просто вызываете метод класса A
.
* Как вы заметили, C.__init__()
никогда не вызывается.Тем не менее, C
по-прежнему отображается в D.__bases__
:
(<class '__main__.B'>, <class '__main__.C'>)
в D.__mro__
:
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
и isinstance(D(), C) is True
.
Короче говоря,Python знает , что C
является суперклассом D
, но вы дали C.__init__
и завершили свою реализацию B.__init__
.