2013-04-09 6 views
14

Betrachtet:Python super() Vererbung und benötigten Argumente

class Parent(object): 

    def altered(self): 
     print "PARENT altered()" 

class Child(Parent): 

    def altered(self): 
     print "CHILD, BEFORE PARENT altered()" 
     super(Child, self).altered() # what are the arguments needed? Why Child and self? 
     print "CHILD, AFTER PARENT altered()" 

In Python 2.7, Warum muss Child als Argument für den Anruf super() weitergegeben werden? Was sind die genauen Feinheiten der Verwendung von Super, anstatt es einfach funktionieren zu lassen.

+7

Soweit ich weiß, hat es mit dem MRO zu tun. Aber ich bin nicht gut genug, um es für eine "echte" Antwort zu erklären. Vielleicht hilft das: http://rhettinger.wordpress.com/2011/05/26/super-considered-super/ Beachten Sie, dass die Argumente in Python 3 nicht mehr benötigt werden. –

+0

Also ist das erste Argument "Child" für die Klasse, in der du bist und nicht die, von der du erben willst, da Parent die Basis ist? So etwas nehme ich an. Auch danke für das Lesen und ich benutze Python 2.7 um klar zu sein. Ich werde weiterlesen über super() –

Antwort

18

super berechnet, welche die nächste Klasse in der Methodenauflösung ist. Die zwei Argumente, die du übergibst, sind das, was sie herausfinden lässt - self gibt es das gesamte MRO über ein Attribut; Die aktuelle Klasse sagt, wo Sie entlang der MRO sind gerade. Also, was Super tatsächlich tut, ist im Grunde:

def super(cls, inst): 
    mro = inst.__class__.mro() # Always the most derived class 
    return mro[mro.index(cls) + 1] 

Der Grund ist es die aktuelle Klasse ist eher als die Basisklasse, da der gesamte Punkt Super zu haben, ist eine Funktion zu haben, was funktioniert, dass Basisklasse ist eher als dass man explizit darauf verweisen muss - was zu Problemen führen kann, wenn sich der Name der Basisklasse ändert, wenn Sie nicht genau wissen, wie die Elternklasse aufgerufen wird (denken Sie an Factory-Funktionen wie namedtuple, die eine neue Klasse ausspucken) in Multi-Vererbungs-Situationen (wobei die nächste Klasse in der MRO möglicherweise keine der Basen der aktuellen Klasse ist).

+0

Der Grund, dass es die aktuelle Klasse ist und nicht die Basisklasse ist, weil der ganze Punkt von super eine Funktion haben soll, die herausfindet, was diese Basisklasse ist, anstatt explizit darauf verweisen zu müssen . Ich denke, diese Zeile, die du angegeben hast, hat es gut zusammengefasst. Ich werde in das MRO schauen und erkennen, dass dies nur eine Facette von Python 2.x ist, da Python 3 diese Argumente nicht benötigt. Vielen Dank. –

+3

@klandshome Python 3's funktioniert genau auf die gleiche Weise - es hat nur einige interessante Erweiterungen, um in der Lage zu sein, die Argumente für sich selbst herauszufinden (indem man den Call-Stack kontrolliert), anstatt sie zu übergeben. – lvc

+1

Hmm. Tolle Information. Der Aufrufstapel. Ich habe viel gelernt. Vielen Dank. –

Verwandte Themen