Supponiamo che io abbia uno scenario di ereditarietà multipla:
class A(object):
# code for A here
class B(object):
# code for B here
class C(A, B):
def __init__(self):
# What's the right code to write here to ensure
# A.__init__ and B.__init__ get called?
Ci sono due approcci tipici di scrittura C
's __init__
:
- (vecchio stile)
ParentClass.__init__(self)
- (Stile più recente)
super(DerivedClass, self).__init__()
Tuttavia, in entrambi i casi, se le classi parent ( A
e B
) non seguono la stessa convenzione, il codice non funzionerà correttamente (alcuni potrebbero non essere rilevati o essere chiamati più volte).
Quindi qual è di nuovo il modo corretto? È facile dire "basta essere coerenti, seguire l'uno o l'altro", ma se A
o B
provengono da una libreria di terze parti, che cosa succede? Esiste un approccio che può garantire che tutti i costruttori della classe genitore vengano chiamati (e nell'ordine corretto e solo una volta)?
Modifica: per vedere cosa intendo, se lo faccio:
class A(object):
def __init__(self):
print("Entering A")
super(A, self).__init__()
print("Leaving A")
class B(object):
def __init__(self):
print("Entering B")
super(B, self).__init__()
print("Leaving B")
class C(A, B):
def __init__(self):
print("Entering C")
A.__init__(self)
B.__init__(self)
print("Leaving C")
Quindi ottengo:
Entering C
Entering A
Entering B
Leaving B
Leaving A
Entering B
Leaving B
Leaving C
Si noti che B
init viene chiamato due volte. Se lo faccio:
class A(object):
def __init__(self):
print("Entering A")
print("Leaving A")
class B(object):
def __init__(self):
print("Entering B")
super(B, self).__init__()
print("Leaving B")
class C(A, B):
def __init__(self):
print("Entering C")
super(C, self).__init__()
print("Leaving C")
Quindi ottengo:
Entering C
Entering A
Leaving A
Leaving C
Nota che B
init non viene mai chiamato. Quindi sembra che se non conosco / controllo gli init delle classi che eredito da ( A
e B
) non posso fare una scelta sicura per la classe che sto scrivendo ( C
).