In dem Buch Python in a Nutshell (2. Ausgabe) gibt es ein Beispiel, das
alte Stilklassen verwendet, um zu demonstrieren, wie Methoden in klassischer Auflösungsreihenfolge aufgelöst werden und
wie sie sich von der neuen Reihenfolge unterscheiden.
Ich habe das gleiche Beispiel versucht, indem ich das Beispiel in einem neuen Stil umgeschrieben habe, aber das Ergebnis unterscheidet sich nicht von dem, was mit alten Stilklassen erzielt wurde. Die Python-Version, mit der ich das Beispiel ausführe, ist 2.5.2. Unten ist das Beispiel:
class Base1(object):
def amethod(self): print "Base1"
class Base2(Base1):
pass
class Base3(object):
def amethod(self): print "Base3"
class Derived(Base2,Base3):
pass
instance = Derived()
instance.amethod()
print Derived.__mro__
Der Aufruf wird instance.amethod()
gedruckt Base1
, aber nach meinem Verständnis des MRO mit neuem Klassenstil sollte die Ausgabe gewesen sein Base3
. Der Anruf wird Derived.__mro__
gedruckt:
(<class '__main__.Derived'>, <class '__main__.Base2'>, <class '__main__.Base1'>, <class '__main__.Base3'>, <type 'object'>)
Ich bin mir nicht sicher, ob mein Verständnis von MRO mit neuen Stilklassen falsch ist oder ob ich einen dummen Fehler mache, den ich nicht erkennen kann. Bitte helfen Sie mir beim besseren Verständnis von MRO.
quelle
Die Reihenfolge der Python-Methodenauflösung ist tatsächlich komplexer als nur das Verständnis des Rautenmusters. Um es wirklich zu verstehen, werfen Sie einen Blick auf die C3-Linearisierung . Ich habe festgestellt, dass es wirklich hilfreich ist, print-Anweisungen zu verwenden, wenn Methoden zur Verfolgung der Reihenfolge erweitert werden. Was denkst du zum Beispiel wäre die Ausgabe dieses Musters? (Hinweis: Das 'X' soll zwei sich kreuzende Kanten sein, kein Knoten, und ^ bezeichnet Methoden, die super () aufrufen.)
Hast du ABDCEFG bekommen?
Nach vielen Versuchen und Fehlern kam ich zu einer informellen graphentheoretischen Interpretation der C3-Linearisierung wie folgt: (Jemand, bitte lassen Sie mich wissen, wenn dies falsch ist.)
Betrachten Sie dieses Beispiel:
quelle
super
hat Argumente benötigt.Das Ergebnis ist korrekt. Versuchen Sie, die Basisklasse von
Base3
to zu ändern ,Base1
und vergleichen Sie sie mit derselben Hierarchie für klassische Klassen:Jetzt gibt es aus:
Lesen Sie diese Erklärung für weitere Informationen.
quelle
Sie sehen dieses Verhalten, weil die Methodenauflösung in der Tiefe und nicht in der Breite an erster Stelle steht. Dervieds Erbschaft sieht aus wie
So
instance.amethod()
amethod
, also wird es aufgerufen.Dies spiegelt sich in wider
Derived.__mro__
. Einfach wiederholenDerived.__mro__
und anhalten, wenn Sie die gesuchte Methode gefunden haben.quelle