К сожалению, нет никакого способа, чтобы сделать эту работу, используя super()
без изменения базовых классов. Любой вызов конструкторов для B
или C
собирается попробовать и вызвать следующий класс в Method Resolution Order, который всегда будет B
или C
вместо A
класса, что класс конструкторы B
и C
предположить.
Альтернативой является вызов конструкторов явно без использования super()
в каждом классе.
class A(object):
def __init__(self, a):
object.__init__()
self.a = a
class B(A):
def __init__(self, a, b):
A.__init__(self, a)
self.b = b
class C(object):
def __init__(self, a, c):
A.__init__(self, a)
self.c = c
class D(B, C):
def __init__(self, a, b, c, d):
B.__init__(self, a, b)
C.__init__(self, a, c)
self.d = d
Существует еще недостаток здесь, как A
конструктор будет вызван дважды, что на самом деле не имеет большого влияния в этом примере, но может вызвать проблемы в более сложных конструкторах. Вы можете включить проверку, чтобы предотвратить запуск конструктора более одного раза.
class A(object):
def __init__(self, a):
if hasattr(self, 'a'):
return
# Normal constructor.
Некоторые называют бы это недостатком super()
, и это в каком-то смысле, но это также просто недостаток множественного наследования в целом. Модели наследования алмазов часто подвержены ошибкам. И многие обходные пути для них приводят к еще более запутанному и подверженному ошибкам коду. Иногда лучший ответ - попытаться реорганизовать ваш код, чтобы использовать меньшее количество наследований.
Возможный дубликат [Как работает супер() Python с множественным наследованием?] (Http://stackoverflow.com/questions/3277367/how-does-pythons-super-work-with-multiple-inheritance) – erip
вы может дважды вызывать '__init__' для' B' и 'C'. – sobolevn
Но тогда 'A .__ init__' будет вызываться дважды, не так ли? – user5459381