python多继承时,函数调用顺序
问题的根源在于MRO算法
什么是MRO算法呢?Method Resolution Order。即方法解析顺序。
什么是方法解析顺序呢?就是当存在类的继承关系时,在子类父类中查找一个方法的顺序。
我们可以在类的.__mro__中查看该类的MRO。
比如 有 A,B(A), C(A), D(B, C)的类定义,我们可以查看D.__mro__会看到D,B,C,A,Object的顺序,也可以查看B.__mro__会看到B,A,Object。
通常有两种情况会触发按照mro的查找。
一,子类里没有实现这个方法。就会按照mro的顺序去找,直到找到为止。
比如 有 A, B: func(), C: func(), D(B,C),然后创建d=D(),调用d.func()。
因为class D没有实现func,于是按照mro的顺序,在B里面找到了并调用,然后结束。
二,super()方法,当使用此方法时候,会在mro里继续寻找下一个符合条件的函数并执行。
比如B:func()里面有super().func()。那么d.func()会依次分别调用B:func()和C:func()。
super方法常见于__init__中,因为我们要正确但不重复的初始化所有的父类。
只需要在A, B, C,D的__init__里都添加super().init(),调用d.init()时候,就会按照mro的顺序即D, B, C, A, Object依次调用其__init__()方法。
至于mro的顺序是如何计算的,可以详见下面的link。python 2.2 以前是Depth first left to right(DLR)算法,python 2.3以后是C3 Linearization algorithm 算法。这里就不再细说了。
参考文献
[1]: https://www.geeksforgeeks.org/method-resolution-order-in-python-inheritance/