294 votes

La chaîne de l'appel de parent constructeurs en python

Tenez compte de ceci: une base de classe A, de classe B hérite de A, de classe C hérite de B. Ce qui est une façon générique pour appeler un constructeur de la classe parent dans un constructeur? Si cela semble encore trop vague, voici un peu de code.

class A(object):
    def __init__(self):
        print "Constructor A was called"

class B(A):
    def __init__(self):
        super(B,self).__init__()
        print "Constructor B was called"

class C(B):
    def __init__(self):
        super(C,self).__init__()
        print "Constructor C was called"

c = C()

C'est la façon dont je le fais maintenant. Mais il semble encore un peu trop non générique, vous devez passer un bon type à la main.

Maintenant, j'ai essayé à l'aide d' self.__class__ comme premier argument à super(), mais, évidemment, ça ne fonctionne pas - si vous le mettez dans le constructeur de C - assez juste, B du constructeur est appelé. Si vous faites la même chose dans le cas B, le "soi" des points encore à une instance de C, donc vous vous retrouvez l'appel B du constructeur (c'est la fin d'une récursion infinie).

Il n'y a pas besoin de penser au sujet de diamant héritage pour l'instant, je suis juste intéressé par la résolution de ce problème spécifique.

213voto

ironfroggy Points 3496

Python 3 inclut une amélioration de super() qui permet de l'utiliser comme ceci:

super().__init__(args)

170voto

dF. Points 29787

La façon dont vous le faites est en effet celle qui est recommandée (pour Python 2.x).

La question de savoir si la classe est passé explicitement super est une affaire de style plutôt que de la fonctionnalité. De passage à la classe d' super s'inscrit dans Python philosophie de "explicite est mieux que l'implicite".

29voto

Jay Parikh Points 31

Vous pouvez simplement écrire :

class A(object):

    def __init__(self):
        print "Constructor A was called"

class B(A):

    def __init__(self):
        A.__init__(self)
        # A.__init__(self,<parameters>) if you want to call with parameters
        print "Constructor B was called"

class C(B):

    def __init__(self):
        # A.__init__(self) # if you want to call most super class...
        B.__init__(self)
        print "Constructor C was called"

-1voto

MrGray Points 454

Celui-ci fonctionne très bien pour moi:

super(eval(self.__class__.__name__), self).__init__()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X