python 类 五 : 多重继承的MRO顺序
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 类 五 : 多重继承的MRO顺序相关的知识,希望对你有一定的参考价值。
这个系列的讲述,部分内容或者例子来自 <<python 核心编程 第二版>>
python 的类有经典类和新式类之分,在多重继承的时候,继承到的方法的搜索的顺序根据类的类型不同也是不同的。
先来讲经典类:
经典类的特点就是不继承自任何类:
#coding:utf-8 class p_1: def foo(self): print ‘called p1-foo()‘ class p_2: def foo(self): print ‘called p2-foo()‘ def bar(self): print ‘called p2-bar‘ class c_1(p_1,p_2): pass class c_2(p_1,p_2): def bar(self): print ‘called c2-bar()‘ class c_3(c_1,c_2): pass c3 = c_3() c3.foo() c3.bar()
这个继承关系如上图所示
经典类的多重继承,子类对于继承到的父类的方法的搜索顺序是: 深度优先,从左至右。
那么,对于 c3这个实例,来自于类 c_3。
c_3没有自己实现 foo 和 bar 方法 。
那么,按照深度优先,从左至右的原则。
对于foo方法:
先找自己,自己没有实现foo,再向上找c_2 ,c_2也没有实现foo,继续向上找c_1,c_1也没有实现foo,继续向上找p_1,p_1实现了foo方法。
则c_3.foo()的输出是:called p1-foo()
对于bar方法:
先找自己,自己没有bar,再向上找c_1,c_1没有实现bar,继续向上找p_1,p_1实现了bar方法。
则c_3.bar()的输出是: called p2-bar
而如果是新式类:
则MRO的搜索顺序是 广度优先,从左至右
则同样的代码(只是用新式类来声明):
#coding:utf-8 class p_1(object): def foo(self): print ‘called p1-foo()‘ class p_2(object): def foo(self): print ‘called p2-foo()‘ def bar(self): print ‘called p2-bar‘ class c_1(p_1,p_2): pass class c_2(p_1,p_2): def bar(self): print ‘called c2-bar()‘ class c_3(c_1,c_2): pass c3 = c_3() c3.foo() c3.bar()
对于c3.foo()
先找c3自己,c_3自己没有实现foo,继续向上找c_1,c_1也没有实现foo,则找c_1的兄弟c_2,c_2也没有实现foo,则继续向上找p_1,p_1实现了foo
因此,c3.foo的输出是 called p1-foo()
对于c3.bar()
先找c3自己,c_3自己没有实现bar,则继续向上找c_1,c_1自己也没有实现bar,则继续找c_1的兄弟c_2,c_2实现了bar方法。
则c3.bar的输出是 called c2-bar()
总结:
对于新式类,是广度优先,从左至右的顺序搜索。
对于经典类,是深度优先,从左至右的顺序搜索。
以上是关于python 类 五 : 多重继承的MRO顺序的主要内容,如果未能解决你的问题,请参考以下文章
Method Resolve Order (MRO) - 类对象属性的解析顺序