Disons que j'ai un scénario d'héritage multiple:
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?
Il y a deux approches typiques de l' écriture C
de __init__
:
- (à l'ancienne)
ParentClass.__init__(self)
- (style plus récent)
super(DerivedClass, self).__init__()
Cependant, dans les deux cas, si les classes parentes ( A
et B
) ne suivent pas la même convention, le code ne fonctionnera pas correctement (certaines peuvent être manquées ou être appelées plusieurs fois).
Alors, quelle est la bonne manière encore? Il est facile de dire "soyez cohérent, suivez l'un ou l'autre", mais si A
ou B
proviennent d'une bibliothèque tierce, que faire alors? Existe-t-il une approche qui puisse garantir que tous les constructeurs de classes parents sont appelés (et dans le bon ordre, et une seule fois)?
Edit: pour voir ce que je veux dire, si je fais:
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")
Ensuite, je reçois:
Entering C
Entering A
Entering B
Leaving B
Leaving A
Entering B
Leaving B
Leaving C
Notez que B
init est appelé deux fois. Si je fais:
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")
Ensuite, je reçois:
Entering C
Entering A
Leaving A
Leaving C
Notez que B
init n'est jamais appelé. Il semble donc qu'à moins de connaître / contrôler les init des classes dont j'hérite ( A
et B
) je ne peux pas faire un choix sûr pour la classe que j'écris ( C
).