Один правильный способ использования super
здесь будет
class A:
def __init__(self, a, **kwargs):
super().__init__(**kwargs)
self.a = a
class B:
def __init__(self, b, **kwargs):
super().__init__(**kwargs)
self.b = b
class C1(A, B):
pass
class C2(A, B):
def __init__(self, a, b, **kwargs):
super().__init__(a=a, b=b, **kwargs)
c1 = C1(a="foo", b="bar")
c2 = C2(a="foo", b="bar")
Порядок разрешения метода для C
равен [C, A, B, object]
.Каждый раз, когда вызывается super()
, он возвращает прокси для класса next в MRO, в зависимости от того, где super()
вызывается в то время.
При определенииC
, в зависимости от того, хотите ли вы определить C.__init__
с помощью подписи, в которой упоминаются два аргумента A
и B
, необходимые для инициализации.С C1
, C1.__init__
не определено, поэтому вместо него будет вызываться A.__init__
.С C2
вам необходимо явно вызвать следующий метод __init__
в цепочке.
C
, зная, что это подкласс A
и B
, должен как минимум предоставитьожидаемые аргументы для известных восходящих __init__
методов.
A.__init__
будут передавать все кроме a
методу __init__
следующего класса.
B.__init__
передаст все, что получит , за исключением b
.
object.__init__
, наконец, будет вызван, и, если все предыдущие классы правильно удалили введенные аргументы ключевого слова, не получатдополнительные аргументы.
Изменение порядка, в котором называются различные __init__
, означает изменение MRO, что означает изменение порядка базовых классов.Если вы хотите большего контроля, чем это, то кооперативное множественное наследование не для вас.