2017-04-05 4 views
1

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   
+0

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

+0

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. –

+2

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

Antwort

1

Ich denke, es ist wichtig zu erwähnen, dass super nicht die „Eltern-Klasse“ nicht nennen, aber die „nächste Klasse in der MRO“.

Sie sagten selbst, dass die MRO D -> B -> C -> A für D ist. So super in D.f-B lösen wird, super in B.f wird C lösen und schließlich super in C.f wird A lösen.

Wenn Sie weitere Informationen benötigen, gibt es mehrere Ressourcen (mit unterschiedlichen Interpretationen über die Nützlichkeit von super) verfügbar:

Verwandte Themen