2
votes

Une sous-classe doit-elle initialiser une super-classe vide?

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?


0 commentaires

3 Réponses :


2
votes

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'


0 commentaires

1
votes

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.


0 commentaires

6
votes

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__.


2 commentaires

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 ...