Dies wird von Guido selbst in seinem Blog-Beitrag Method Resolution Order (einschließlich zweier früherer Versuche) mit einer angemessenen Menge an Details beschrieben .
In Ihrem Beispiel Third()
wird anrufen First.__init__
. Python sucht nach jedem Attribut in den Eltern der Klasse, da diese von links nach rechts aufgelistet sind. In diesem Fall suchen wir __init__
. Also, wenn Sie definieren
class Third(First, Second):
...
Python beginnt mit dem Betrachten First
und wenn First
es das Attribut nicht hat, wird es sich ansehen Second
.
Diese Situation wird komplexer, wenn die Vererbung beginnt, Pfade zu kreuzen (z. B. wenn sie First
vererbt wird Second
). Lesen Sie den obigen Link, um weitere Informationen zu erhalten. Kurz gesagt, Python versucht, die Reihenfolge beizubehalten, in der jede Klasse in der Vererbungsliste angezeigt wird, beginnend mit der untergeordneten Klasse selbst.
Also zum Beispiel, wenn Sie hatten:
class First(object):
def __init__(self):
print "first"
class Second(First):
def __init__(self):
print "second"
class Third(First):
def __init__(self):
print "third"
class Fourth(Second, Third):
def __init__(self):
super(Fourth, self).__init__()
print "that's it"
der MRO wäre [Fourth, Second, Third, First].
Übrigens: Wenn Python keine kohärente Reihenfolge für die Methodenauflösung findet, wird eine Ausnahme ausgelöst, anstatt auf ein Verhalten zurückzugreifen, das den Benutzer überraschen könnte.
Bearbeitet, um ein Beispiel für eine mehrdeutige MRO hinzuzufügen:
class First(object):
def __init__(self):
print "first"
class Second(First):
def __init__(self):
print "second"
class Third(First, Second):
def __init__(self):
print "third"
Sollte Third
MRO sein [First, Second]
oder [Second, First]
? Es gibt keine offensichtliche Erwartung und Python wird einen Fehler auslösen:
TypeError: Error when calling the metaclass bases
Cannot create a consistent method resolution order (MRO) for bases Second, First
Bearbeiten: Ich sehe mehrere Leute argumentieren, dass die obigen Beispiele keine super()
Aufrufe enthalten. Lassen Sie mich daher erklären: In den Beispielen soll gezeigt werden, wie die MRO aufgebaut ist. Sie sollen nicht "first \ nsecond \ Third" oder was auch immer drucken. Sie können - und sollten natürlich mit dem Beispiel herumspielen, super()
Aufrufe hinzufügen , sehen, was passiert, und ein tieferes Verständnis des Vererbungsmodells von Python erlangen. Aber mein Ziel hier ist es, es einfach zu halten und zu zeigen, wie der MRO aufgebaut ist. Und es ist so gebaut, wie ich es erklärt habe:
>>> Fourth.__mro__
(<class '__main__.Fourth'>,
<class '__main__.Second'>, <class '__main__.Third'>,
<class '__main__.First'>,
<type 'object'>)
super()
von Nutzen ist. Ich würde nicht empfehlen, es mit Klassen zu verwenden, die lineare Vererbung verwenden, wo es nur nutzlosen Overhead ist.