多继承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算法.

    

猜你喜欢

转载自blog.csdn.net/Li_G_yuan/article/details/80412277