2017-04-05 159 views
1

我正在玩類,看看mro如何在python3中工作。我得到了主要想法:方法從左到右,先深入解決,如果有一個共同的父親,它就在最後。mro:爲什麼來自父母的方法都被調用?

這裏是東西顯然很簡單,不表現得像我想到:

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() 

現在,由於MRO是D -> B -> C -> A我希望super打電話B.f,使其打印:

calling D 
calling B 
calling A 
A 
B 
D 

但它實際上也稱爲C.f

calling D 
calling B 
calling C 
calling A 
A   
C   
B   
D   

這是爲什麼?

我期望C.f不被調用的原因是因爲B作爲方法f,應該停止分辨率。這是如果C不從A繼承的情況:

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

你說這是你的如果MRO是'D - > B - > C - > A',那爲什麼不叫'C.f'?畢竟「C」在MRO中! – MSeifert

+0

嗯,python發現'B'有方法'f',所以它不需要繼續。此外,在我的例子中,如果'C'不從'A'繼承,'C.f'不會被調用。 –

+2

MRO說明調用方法的順序(至少如果每個調用'super'的話)。所以我不明白你的意思是「不需要繼續」。你確實稱之爲「超級」,只要你這樣做,它就會遵循MRO。 – MSeifert

回答

相關問題