Cela m'est venu à l'esprit.
class Parent:
pass
class Child(Parent):
def __init__(self):
# is this necessary?
super().__init__()
Lorsqu'une classe hérite d'une classe vide, la sous-classe doit-elle l'initialiser et pourquoi?
3 Réponses :
Non, ce n'est pas nécessaire. Il est nécessaire lorsque vous souhaitez que la logique du parent s'exécute également.
class Parent:
def __init__(self):
self.some_field = 'value'
class Child(Parent):
def __init__(self):
self.other_field = 'other_value'
super().__init__()
child = Child()
child.some_field # 'value'
Il n'y a aucune exigence dans la langue selon laquelle la sous-classe doit appeler __init__ de la superclasse. Malgré cela, cela est presque toujours nécessaire car la superclasse initialise certains attributs de base et la sous-classe s'attend à ce qu'ils soient initialisés. Donc, si la superclasse __init__ est vide, vous n'avez pas besoin de l'appeler, sinon vous devez le faire.
C'est très bien:
class Parent2:
def __init__(self):
super().__init__()
print('Parent2 initialized')
class Child2(Child, Parent2):
pass
# you'd expect this to call Parent2.__init__, but it won't:
Child2()
C'est aussi bien:
class Parent:
# the __init__ is inherited from parent
pass
class Child(Parent):
def __init__(self):
# this does not call parent's __init__,
pass
Cela peut sembler correct, et fonctionnera généralement bien, mais pas toujours:
class Parent:
# the __init__ is inherited from parent
pass
class Child(Parent):
def __init__(self):
# __init__ is called on parent
super().__init__()
Voici un exemple de problème:
class Parent:
# the __init__ is inherited from parent
pass
class Child(Parent):
# the __init__ is inherited from parent
pass
C'est parce que le MRO de Child2 est: Child2 -> Child -> Parent -> Parent2 -> object.
Child2 .__ init__ est hérité de Child code > et que l'on n'appelle pas Parent2 .__ init__ , à cause de l'appel manquant à super().__init__.
Oh-ho! Ainsi, non seulement vous avez besoin que l'initialisation de la classe dont vous héritez soit vide - vous avez également besoin que l'initialisation de chaque classe de base des classes qui héritent de vous soit vide - difficile!
@MartinBonner Si toutes les classes qui implémentent __init__ appellent également super () .__ init__ , alors tout va bien. Là encore, vous rencontrez des problèmes plus profonds si le __init__ de chaque classe prend des arguments différents, mais c'est une histoire différente ...