Digamos que tengo un escenario de herencia múltiple:
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?
Hay dos enfoques típicos de la escritura C
's __init__
:
- (viejo estilo)
ParentClass.__init__(self)
- (estilo más nuevo)
super(DerivedClass, self).__init__()
Sin embargo, en cualquier caso, si las clases principales ( A
y B
) no siguen la misma convención, entonces el código no funcionará correctamente (algunos pueden perderse o recibir llamadas varias veces).
Entonces, ¿cuál es la forma correcta de nuevo? Es fácil decir "solo sea coherente, siga uno u otro", pero si es A
o B
es de una biblioteca de terceros, ¿entonces qué? ¿Existe un enfoque que pueda garantizar que se llame a todos los constructores de clases principales (y en el orden correcto, y solo una vez)?
Editar: para ver a qué me refiero, si lo hago:
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")
Entonces me sale:
Entering C
Entering A
Entering B
Leaving B
Leaving A
Entering B
Leaving B
Leaving C
Tenga en cuenta que B
el init se llama dos veces. Si lo hago:
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")
Entonces me sale:
Entering C
Entering A
Leaving A
Leaving C
Tenga en cuenta que B
nunca se llama a init. Por lo tanto, parece que a menos que sepa / controle los inicios de las clases que heredo de ( A
y B
) no puedo tomar una decisión segura para la clase que estoy escribiendo ( C
).