mro:为什么来自父母双方的方法都叫?

时间:2017-04-05 17:10:31

标签: python-3.x method-resolution-order

我正在玩类以了解mro在python3中是如何工作的。我有一个主要的想法:方法从左到右,深度先解决,如果有一个共同的父母,它就在最后。

这显然非常简单,不像我期望的那样:

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        

1 个答案:

答案 0 :(得分:1)

我认为值得注意的是super并未调用"父级"但是MRO中的下一课"。

你自己说过,D -> B -> C -> A的MRO是D。因此,super中的D.f将解析为Bsuper中的B.fC解析为superC.f A 1}}将解析为super

如果您需要进一步的信息,可以使用几种资源(对{{1}}的有用性有不同的解释):