Purtroppo, non c'è modo di fare questo lavoro utilizzando super()
senza modificare le classi di base. Qualsiasi chiamata ai costruttori per B
o C
sta andando a cercare e chiamare la classe successiva nella Method Resolution Order, che sarà sempre B
o C
anziché la classe A
che i costruttori della classe B
e C
assumono.
L'alternativa è chiamare i costruttori esplicitamente senza l'uso di super()
in ogni classe.
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
C'è ancora un aspetto negativo qui come il costruttore A
sarebbe chiamato due volte, che in realtà non hanno molto di un effetto in questo esempio, ma può causare problemi nei costruttori più complesse. È possibile includere un controllo per impedire il funzionamento del costruttore più di una volta.
class A(object):
def __init__(self, a):
if hasattr(self, 'a'):
return
# Normal constructor.
Qualcuno potrebbe chiamare questa una lacuna di super()
, ed è in un certo senso, ma è anche solo una lacuna ereditarietà multipla in generale. I modelli di ereditarietà dei diamanti sono spesso soggetti a errori. E un sacco di soluzioni alternative per loro portano a un codice ancora più confuso e soggetto a errori. A volte, la risposta migliore è provare e rifattorizzare il codice per utilizzare meno eredità multiple.
Possibile duplicato di [Come funziona Python super() con ereditarietà multipla?] (Http://stackoverflow.com/questions/3277367/how-does-pythons-super-work-with-multiple- eternity) – erip
tu può chiamare '__init__' due volte per' B' e 'C'. – sobolevn
Ma allora "A .__ init__" verrebbe chiamato due volte, vero? – user5459381