Цепные вызовы родительских инициализаторов в python

Рассмотрим это - базовый класс A, класс B, наследующий от A, класс C, наследующий от B. Каков общий способ вызова инициализатора родительского класса в инициализаторе? Если это все еще звучит слишком расплывчато, вот код.

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

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

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

c = C()

Вот как я это делаю сейчас. Но это все еще кажется не слишком общим - вы все равно должны передать правильный тип вручную.

Теперь я попытался использовать self.__class__ в качестве первого аргумента для super(), но, очевидно, он не работает - если вы поместите его в инициализатор для C - достаточно справедливо, вызывается инициализатор B. Если вы сделаете то же самое в B, "self" все еще будет указывать на экземпляр C, поэтому вы в конечном итоге снова вызовете инициализатор B (это заканчивается бесконечной рекурсией).

Пока не нужно думать о наследовании алмазов, я просто заинтересован в решении этой конкретной проблемы.

Ответ 1

То, как вы это делаете, действительно рекомендуется (для Python 2.x).

Вопрос о том, передается ли класс явным образом в super, является вопросом стиля, а не функциональности. Передача класса в super соответствует философии Python "явный лучше, чем неявный".

Ответ 2

Python 3 включает улучшенный super(), который позволяет использовать вот так:

super().__init__(args)

Ответ 3

Вы можете просто написать:

class A(object):

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

class B(A):

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

class C(B):

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