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()

总结:

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

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

时间: 2024-12-28 20:36:35

python 类 五 : 多重继承的MRO顺序的相关文章

Method Resolution Order – Python类的方法解析顺序

在支持多重继承的编程语言中,查找方法具体来自那个类时的基类搜索顺序通常被称为方法解析顺序(Method Resolution Order),简称MRO.(Python中查找其它属性也遵循同一规则.)对于只支持单重继承的语言,MRO十分简单:但是当考虑多重继承的情况时,MRO算法的选择非常微妙.Python先后出现三种不同的MRO:经典方式.Python2.2 新式算法.Python2.3 新式算法(也称作C3).Python 3中只保留了最后一种,即C3算法. 经典类采用了一种简单MRO机制:查

Method Resolve Order (MRO) - 类对象属性的解析顺序

Method Resolve Order (MRO) - 类对象属性的解析顺序 Python 支持多重继承, 此时就需要解决按照何种顺序来解析属性的问题.类的继承关系在一个特殊的类属性中指定(__mro__).这个属性的作用是按照序列出类及其超类, python 会按照这个顺利搜索方法.任何实现了多重继承的语言都要处理潜在的命名冲突问题,这种冲突由不相关的父类实现的同名方法所引起的,称为'菱形问题'. 举个例子, 1 class A(list): 2 def disp(self): 3 prin

python类中super()和__init__()的区别

本文和大家分享的主要是python开发中super()和__init__()的区别,希望通过本文的分享,对初学者学习这部分内容有所帮助. 1.单继承时super()和__init__()实现的功能是类似的 class Base(object): def __init__(self): print 'Base create' class childA(Base): def __init__(self): print 'creat A ', Base.__init__(self) class chi

第六章 Python类(面向对象编程)

什么是面向对象编程? 面向对象编程(Object Oriented Programming,OOP,面向对象程序设计)是一种计算机编程架构.Python就是这种编程语言. 面向对象程序设计中的概念主要包括:对象.类.继承.动态绑定.封装.多态性.消息传递.方法. 1)对象:类的实体,比如一个人. 2)类:一个共享相同结构和行为的对象的集合.通俗的讲就是分类,比如人是一类,动物是一类. 3)继承:类之间的关系,比如猫狗是一类,他们都有四条腿,狗继承了这个四条腿,拥有了这个属性. 4)动态绑定:在不

Python进阶-继承中的MRO与super

摘要本文讲述Python继承关系中如何通过super()调用"父类"方法,super(Type, CurrentClass)返回CurrentClass的MRO中Type的下一个类的代理:以及如何设计Python类以便正确初始化. 1. 单继承中父类方法调用 在继承中,调用父类方法是很有必要的.调用父类方法的场景有很多: 比如必须调用父类的构造方法__init__才能正确初始化父类实例属性,使得子类实例对象能够继承到父类实例对象的实例属性: 再如需要重写父类方法时,有时候没有必要完全摒

python类

1.基本语法 class class_name(base_class):  base_class是它继承的父类 class_var def methods(self,args): statements 经典类.新式类 版本2和版本3的区别,3都是新式类 经典类和新式类的区别: 1)__slots__, 新式类里有这个,‘槽’的意思,对属性的一个限制,只能访问槽里边的属性. 2)继承顺序,super 3)__new__, 4)__getattribute__ 因为Python是动态的,所以可以随便

python 类的定义和继承

python 2 中类 一.类定义: ? 1 2 class <类名>:   <语句> 类实例化后,可以使用其属性,实际上,创建一个类之后,可以通过类名访问其属性如果直接使用类名修改其属性,那么将直接影响到已经实例化的对象 类的私有属性:__private_attrs  两个下划线开头,声明该属性为私有,不能在类地外部被使用或直接访问在类内部的方法中使用时 self.__private_attrs  类的方法在类地内部,使用def关键字可以为类定义一个方法,与一般函数定义不同,类方

python类及其方法

python类及其方法 一.介绍 在 Python 中,面向对象编程主要有两个主题,就是类和类实例类与实例:类与实例相互关联着:类是对象的定义,而实例是"真正的实物",它存放了类中所定义的对象的具体信息. 类有这样一些的优点: 1.类对象是多态的:也就是多种形态,这意味着我们可以对不同的类对象使用同样的操作方法,而不需要额外写代码. 2.类的封装:封装之后,可以直接调用类的对象,来操作内部的一些类方法,不需要让使用者看到代码工作的细节. 3.类的继承:类可以从其它类或者元类中继承它们的

python类的相关知识第二部分

类的继承.多态.封装 一.类的继承 1.应用场景: 类大部分功能相同,大类包含小类的情况 例如: 动物类 共性:都要吃喝拉撒.都有头有脚 特性: 猫类.走了很轻,叫声特别,喜欢白天睡觉 狗类.的叫声很大,晚上睡觉 2.继承顺序 在python2版本中多重继承有分两种继承循序 (1).一直往上找 .找到最高级的父类再重另外一个分支找,直到找到为止. (2).一直往上找,找到最高级父类的下一层后就不找了.从另外一个分支找,另外一个分支没找到最后才找最高级的父类. 再python3中只有第一种继承循序