问题
我们都知道python中允许多继承,使用super来调用父类,但是对于多继承的顺序总是弄不清楚,所以自己写了代码来弄清楚一下具体顺序。
代码
1 |
|
输出结果
1 | B1.__init__ |
- 第一种A和B的__init__中都调用了super方法,此时在C中调用super,发现先输出B,再输出A。而Test2调用只输出了A。
- 第二种A和B的__init__中都没调用super方法,此时在C中调用super,发现只输出A。而Test2调用也只输出了A。
- 第三张我们不用super,改用cls.Method调用,这个好理解,直接按照我们调用的顺序输出,Test2也一样。
MRO算法
这里也大致说下MRO算法:1
2
3class A(O):pass
class B(O):pass
class C(A, B):pass
此时MRO(C) = [C] + merge(mro)1
2
3mro(C) = [C] + merge(mro(A), mro(B), [A,B])
# 上面这个merge这个是按照class C(A, B)中AB的顺序来的
= [C] + merge([A,O], [B,O], [A,B])
执行merge操作的序列为[A,O]、[B,O]、[A,B]
A是序列[A,O]中的第一个元素,在序列[B,O]中不出现,在序列[A,B]中也是第一个元素,所以从执行merge操作的序列([A,O]、[B,O]、[A,B])中删除A,合并到当前mro中。1
mro(C) = [C,A] + merge([O], [B,O], [B])
再执行merge操作,O是序列[O]中的第一个元素,但O在序列[B,O]中出现并且不是其中第一个元素。继续查看下一个元素,也就是[B,O]的第一个元素B,B满足是所有序列中的第一个元素条件,所以从执行merge操作的序列中删除B,合并到[C, A]中。1
2mro(C) = [C,A,B] + merge([O], [O])
= [C,A,B,O]
所以C的顺序为:C、A、B、O(object),复合上面C.mro的输出。
总结一下:从头开始,不断寻找满足所有出现的序列中的第一个元素,找到合并到mro中,删除所有序列中的该元素,继续寻找
分析
通过查找资料,发现这里的顺序是通过一个叫MRO算法生成的,具体可以点击链接看看。
mro算法是求继承顺序的,所以对于一
- 先运行A的__init__,然后A又调用super
- 运行B的__init__,然后B调用super
- 运行object的__init__。
- 打印输出B.__init__。
- 打印输出A.__init__。
- 打印输出C.__init__。
对于二同理分析即可。