2017-04-05 112 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

回答

相关问题