it-swarm.com.de

Kettenaufrufende übergeordnete Initialisierer in python

Betrachten Sie Folgendes: Eine Basisklasse A, eine Klasse B, die von A erbt, eine Klasse C, die von B erbt. Was ist eine generische Methode, um einen Initialisierer einer übergeordneten Klasse in einem Initialisierer aufzurufen? Wenn dies immer noch zu vage klingt, finden Sie hier einen Code.

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()

So mache ich es jetzt. Aber es scheint immer noch ein bisschen zu ungewöhnlich - Sie müssen immer noch einen korrekten Typ von Hand übergeben.

Jetzt habe ich versucht, self.__class__ als erstes Argument für super (), aber offensichtlich funktioniert es nicht - wenn Sie es im Initialisierer für C ablegen - wird der Initialisierer von B aufgerufen. Wenn Sie dasselbe in B tun, zeigt "self" immer noch auf eine Instanz von C, sodass Sie den Initialisierer von B erneut aufrufen (dies endet in einer unendlichen Rekursion).

Im Moment besteht kein Grund, über die Vererbung von Diamanten nachzudenken. Ich bin nur daran interessiert, dieses spezielle Problem zu lösen.

276
shylent

Die Art und Weise, wie Sie es tun, ist in der Tat die empfohlene (für Python 2.x).

Die Frage, ob die Klasse explizit an super übergeben wird, ist eher eine Frage des Stils als der Funktionalität. Das Übergeben der Klasse an super passt zu Pythons Philosophie "explizit ist besser als implizit".

164
dF.

Python 3 enthält ein verbessertes super (), das die Verwendung wie folgt ermöglicht:

super().__init__(args)
191
ironfroggy

Sie können einfach schreiben:

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"
25
Jay Parikh