Digamos que eu tenha um cenário de herança múltipla:
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?
Há duas abordagens típicas para escrever C
's __init__
:
- (estilo antigo)
ParentClass.__init__(self)
- (estilo mais recente)
super(DerivedClass, self).__init__()
No entanto, em ambos os casos, se as classes pai ( A
e B
) não seguirem a mesma convenção, o código não funcionará corretamente (alguns podem ser perdidos ou chamados várias vezes).
Então, qual é o caminho correto de novo? É fácil dizer "apenas ser consistente, siga um ou outro", mas se A
ou B
são de uma biblioteca parte 3, o que então? Existe uma abordagem que pode garantir que todos os construtores da classe pai sejam chamados (e na ordem correta e apenas uma vez)?
Edit: para ver o que quero dizer, se eu fizer:
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")
Então eu recebo:
Entering C
Entering A
Entering B
Leaving B
Leaving A
Entering B
Leaving B
Leaving C
Note que B
o init é chamado duas vezes. Se eu fizer:
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")
Então eu recebo:
Entering C
Entering A
Leaving A
Leaving C
Note que B
o init nunca é chamado. Parece que, a menos que eu conheça / controle os init das classes que herdo ( A
e B
), não posso fazer uma escolha segura para a classe que estou escrevendo ( C
).