写在前面
一个类可以有多个父类, 在类的多继承中,如果继承多个父类方法,调用父类方法时(父类名.方法),会造成父类方法中某些数据被重复调用,所以建议使用super()方法,那么,多继承在python解释器中时怎样调用它的各个父类方法呢?在python类中,有一个内置方法__mro__,它返回一个元祖,保存父类的调用顺序,能够保证每个父类都会被调用,而且只被调用一次.下面看一张类图:
在上图中,怎么可以得到mro的调用顺序呢?我们知道,多继承中,使用super()调用的顺序是根据C3算法来调用的
而C3算法保证只会调用一次,C3算法根据B-Tree来计算得出的,我们要是使用B-Tree来计算得出
上图的MRO执行顺序会很复杂,这里,我介绍一个对算法比较有研究的哥们教给我的方法:
在上面的类图中,可以通过极左原理来推算MRO的顺序,具体怎么做呢?
1.首先,从根开始,寻找没有被指向的,那么第一个就是A
2.如果有多个,根据极左原理选择最左的类,之后将这个类加入MRO,并且删除这个类以及和它相关的指向边,由此可以得出B和D
3.左边的指向边完了,再次根据极左原理寻找有指向边的父类,可以得出C和E
4.以此类推,只剩下了孤单的F了,当所有指向边都移除之后,就剩下了最后一个基类O
那么,我们最后就可以得到最终MRO的顺序为[A,B,D,C,E,F,O]
是不是很简单?这是一种偷懒的做法,当然,如果想深究MRO的顺序,可以查看python解释器的源码,可以去学学C3算法.
总结
- 在类继承中,尽量不要使用类名.方法(self)去调用父类方法,会造成重复调用问题。
- 在多继承中,super()的执行顺序是取决于mro顺序,调用方式如下
类名.mro()或者类名.__mro __