Ich führe Python 2.5, so dass diese Frage möglicherweise nicht auf Python 3 zutrifft. Wenn Sie eine Diamant-Klassenhierarchie mit Mehrfachvererbung erstellen und ein Objekt der abgeleiteten Klasse erstellen, macht Python das Right Thing (TM). Es ruft den Konstruktor für die am weitesten abgeleitete Klasse auf, dann die übergeordneten Klassen von links nach rechts, dann das Großelternteil. Ich kenne Pythons MRO; das ist nicht meine Frage. Ich bin gespannt, wie das Objekt von Super tatsächlich erreicht, um Aufrufe von Super in den Elternklassen die richtige Reihenfolge zu kommunizieren. Betrachten Sie dieses Beispiel-Code:Wie macht Pythons "Super" das Richtige?
#!/usr/bin/python
class A(object):
def __init__(self): print "A init"
class B(A):
def __init__(self):
print "B init"
super(B, self).__init__()
class C(A):
def __init__(self):
print "C init"
super(C, self).__init__()
class D(B, C):
def __init__(self):
print "D init"
super(D, self).__init__()
x = D()
Der Code ist die intuitive Sache, es druckt:
D init
B init
C init
A init
Wenn Sie jedoch den Aufruf von super in B init-Funktion auf Kommentar, weder A noch C der init-Funktion wird genannt. Das bedeutet, dass Bs Aufruf an Super irgendwie die Existenz von C in der gesamten Klassenhierarchie kennt. Ich weiß, dass super ein Proxy-Objekt mit einem überladenen get-Operator zurückgibt, aber wie teilt das Objekt, das von super in D'init-Definition zurückgegeben wird, die Existenz von C an das von super in Bs init-Definition zurückgegebene Objekt mit? Ist die Information, dass nachfolgende Aufrufe von super use auf dem Objekt selbst gespeichert sind? Wenn ja, warum ist nicht super statt selbst.super?
Edit: Jekke hat ganz richtig darauf hingewiesen, dass es nicht self.super ist, weil super ein Attribut der Klasse ist, keine Instanz der Klasse. Konzeptionell macht das Sinn, aber in der Praxis ist Super auch kein Attribut der Klasse! Sie können dies im Interpreter testen, indem Sie zwei Klassen A und B erstellen, wobei B von A erbt und dir(B)
aufruft. Es hat keine super
oder __super__
Attribute.
Super ist nicht self.super, weil super eine Eigenschaft der Klasse ist, nicht die Instanz. (Ich verstehe den Rest der Frage nicht wirklich.) –
Irrelevant, vielleicht; aber ich wurde von mehreren Leuten darauf hingewiesen, Python 2.5 nicht mehr zu benutzen, da Python 3 so viele neue Funktionen/Fehler enthält, dass es so viele Bugs gibt. – adam
Editieren zu 'Wie teilt das Objekt, das von super in D'init-Definition zurückgegeben wird, die Existenz von C zu dem Objekt, das von Super in Bs Init-Definition zurückgegeben wird'? Ich glaube, das ist, was Sie fragen - es könnte mehr Sinn machen :) –