这个系列的讲述,部分内容或者例子来自 <<python 核心编程 第二版>>

python 的类有经典类和新式类之分,在多重继承的时候,继承到的方法的搜索的顺序根据类的类型不同也是不同的。

先来讲经典类:

经典类的特点就是不继承自任何类:

#coding:utf-8class 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):    passclass c_2(p_1,p_2):    def bar(self):        print 'called c2-bar()'class c_3(c_1,c_2):    passc3 = 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-8class 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):    passclass c_2(p_1,p_2):    def bar(self):        print 'called c2-bar()'class c_3(c_1,c_2):    passc3 = 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()

总结:

对于新式类,是广度优先,从左至右的顺序搜索。

对于经典类,是深度优先,从左至右的顺序搜索。