class A(object):
def foo(self):
print('foo of A')
class B(A):
pass
class C(A):
def foo(self):
print('foo fo C')
class D(B, C):
pass
class E(D):
def foo(self):
print('foo in E')
super().foo()
super(B, self).foo()
super(C, self).foo()
if __name__ == '__main__':
d = D()
d.foo()
e = E()
e.foo()
print(A.__mro__)
print(B.__mro__)
print(C.__mro__)
print(D.__mro__)
输出
foo fo C
foo in E
foo fo C
foo fo C
foo of A
(<class '__main__.A'>, <class 'object'>)
(<class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
(<class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
进程已结束,退出代码0
super(B, self).foo()的意思是说:
获取 self ,即实例化对象的所属类的mro, 也就是E的__mro__属性,这里是:
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
从mro中 B右边的一个类开始,依次寻找foo()函数。这里是从C开始寻找
一旦找到,就把找到的foo()函数绑定到self对象,并返回
这里C就有foo(),所以输出C的内容
同理super(C, self).foo(),找C右边第一个开始找,输出A的内容
扩展:
具体见大佬文章http://t.csdn.cn/46bCU
super(Leaf, cls).new(cls)的意思是说:
获取cls这个类的mro,这里也是[Leaf, Medium1, Medium2, Base]
从mro中Leaf右边的一个类开始,依次寻找__new__函数
一旦找到,就返回“非绑定”的__new__函数
由于返回的是非绑定的函数对象,因此调用时不能省略函数的第一个参数。这也是这里调用__new__时,需要传入参数cls的原因
同样的,如果我们想从某个mro的某个位置开始查找,只需要修改super的第一个参数就行