Ich spielte mit Klassen, um zu sehen, wie mro
in Python3 funktioniert. Ich habe die Hauptidee: Methoden werden von links nach rechts aufgelöst, Tiefe zuerst und wenn es ein gemeinsames Elternteil gibt, ist es am Ende.mro: Warum werden Methoden von beiden Elternteilen aufgerufen?
Hier ist etwas scheinbar ganz einfach, die nicht wie ich benimmt erwarten:
class A(object):
def f(self):
print("calling A")
print("A")
class B(A):
def f(self):
print("calling B")
super(B, self).f()
print("B")
class C(A):
def f(self):
print("calling C")
super(C, self).f()
print("C")
class D(B,C):
def f(self):
print("calling D")
super(D, self).f()
print("D")
d=D()
d.f()
Da nun der MRO D -> B -> C -> A
I super
erwarten B.f
so zu nennen, dass es druckt:
calling D
calling B
calling A
A
B
D
Aber es tatsächlich anrufen C.f
auch:
calling D
calling B
calling C
calling A
A
C
B
D
Warum ist das?
Der Grund, warum ich erwarte C.f
nicht aufgerufen werden, ist, dass seit B
als Methode f
, sollte die Auflösung zu stoppen. Dies ist der Fall, wenn C
nicht von A
erbt:
class A(object):
def f(self):
print("calling A")
print("A")
class B(A):
def f(self):
print("calling B")
super(B, self).f()
print("B")
class C():
def f(self):
print("calling C")
super(C, self).f()
print("C")
class D(B,C):
def f(self):
print("calling D")
super(D, self).f()
print("D")
d=D()
d.f()
# prints:
# calling D
# calling B
# calling A
# A
# B
# D
Sie sagte es dir Wenn das MRO "D -> B -> C -> A" ist, warum sollte es nicht "C.f" heißen? 'C' ist immerhin im MRO! – MSeifert
Nun Python findet, dass 'B' die Methode' f' hat, so dass es aber nicht fortgesetzt werden muss. Wenn in meinem Beispiel "C" nicht von "A" erbt, wird "C.f" nicht aufgerufen. –
Die MRO gibt an, in welcher Reihenfolge die Methoden aufgerufen werden (zumindest wenn sie jeweils 'super' heißen). Also verstehe ich nicht, was Sie mit "keine Notwendigkeit, weiter" meinen. Sie nennen 'Super' und solange Sie das tun, folgt es dem MRO. – MSeifert