多继承MRO顺序
python是一个面向对象的语言,在我学习python的过程中,很多人都向我说过,python中,一切皆是对象,说到对象这次我就提一下创建实例对象的类.
在我上篇笔记中提过,类是创建实例对象的一种特殊对象,关于对象的详细描述,请查看我的上篇笔记.言归正传,提到类,就不得不提类的三大特性: 封装 继承 多态 本章内容就类的继承来谈谈自己的看法.在类的单继承中,它的继承顺序没什么可说的,这次主要就类的多继承发表自己的看法:
一个类可以有多个父类, 在类的多继承中,如果继承多个父类方法,调用父类方法时(父类名.方法),会造成父类方法中某些数据被重复调用,所以建议使用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算法.