多继承

继承: x是一种y的时候.可以使用继承关系。是"is a"的关系

在python中,支持多继承,一个类可以拥有多个父类。但是多继承中, 存在着这样一个问题,当两个父类中出现了重名方法的时候该怎么办呢? 这时就涉及到如何查找父类方法的问题。即MRO(method resolution order) 问题。在python中这是个很复杂的问题,因为在不同的 python版本中使用的是不同的算法来完成MRO的。

经典类计算MRO用的是深度优先的遍历算法,而新式类的MRO用的是c3算法

##对于经典类和新式类的区分(已经成为过去时了):

在python2中

没有显式声明继承object类的类及其子类,被称为经典类

有显式声明继承object类的类及其子类,被称为新式类,新式类是在python2.2之后才出现的,在此之前都是用的经典类

python3中默认都继承了object类,所以python3中都是新式类。

#经典类的MRO

深度优先:从左子树开始,右子树结束,一条道走到黑

遍历结果: Foo-> H -> G -> F -> E -> D -> B -> A -> C

#新式类的MRO

新式类的MRO是采用的C3算法来完成的,C3的核心是merge

先拆分后合并,合并用merge

merge原则:拿每一项的头和后一项的身体比较,如果出现了,就跳过,从后一项的头继续去比较,如果不出现就拿出这个元素,并删除这个和其他列表中的元素,merge一次后继续从头开始。

 class D(O):
pass
class F(O):
pass
class C(D,F):
pass # c的mro
L[C] = C + merge(DO,FO,DF) #D 和后边其他项的身体都不同,D出来,删除D
= C + D + merge(O,FO,F) #O和第二项的身体相同,O跳过,F和后边其他项的身体都不同,F出来,删除F
= C + D + F + merge(O,O)
= C D F O
 class A:
pass
class B(A):
pass
class C(A):
pass
class D(B, C):
pass
class E(C, A):
pass
class F(D, E):
pass
class M(F, E):
pass
class N:
pass
class P(M,N):
pass
class G(P):
pass
class O:
pass
class X(O):
pass
class H(G, X, F):
pass '''
拆分:(注意拆分时在最后面加上所有的子类名)
L(H) = H + L(G) + L(X) + L(F) + GXF # 合并: H + GPMFDBECAN + X + FDBECA + GXF =HGPMXFDBECAN L(G) = G + L(P) + P # G + PMFDBECAN + P = GPMFDBECAN
L(X) = X + L(O) + O # X + O + O =XO
L(F) = F + L(D) + L(E) + DE # F + DBCA + ECA + DE = FDBECA L(P) = P + L(M) + L(N) + MN # P + MFDBECA + N +MN = PMFDBECAN
L(D) = D + L(B) + L(C) + BC # 合并: D + BA +CA + BC = DBCA
L(E) = E + L(C) + L(A) + CA # 合并: E + CA + A + CA = ECA L(M) = M + L(F) + L(E) + FE # 合并: M + FDBECA + ECA + FE = MFDBECA ''' print(H.__mro__)
结果:
(<class '__main__.H'>, <class '__main__.G'>, <class '__main__.P'>, <class '__main__.M'>, <class '__main__.X'>, <class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class '__main__.N'>, <class '__main__.O'>, <class 'object'>)

超难mro题

##

还有一种计算MRO的方法是通过画图,把继承关系看做一个有向无环图进行遍历也能得到正确结果(遍历规则:找入度为0的节点,有多个时,按从左往右的顺序),相对而言这种方式更便捷,详细见下面文章

关于python中Mro的深度解释

http://python.jobbole.com/85685/

##super()

记住super查找的是MRO列表中的下一个

python记录day_20 多继承的更多相关文章

  1. 深入super,看Python如何解决钻石继承难题 【转】

    原文地址 http://www.cnblogs.com/testview/p/4651198.html 1.   Python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通 ...

  2. python作用域和多继承

    python作用域 python无块级作用域 看c语言代码: #include<stdio.h> int main() { > ) { ; } printf("i = %d ...

  3. python中使用多继承

    python中使用多继承,会涉及到查找顺序(MRO).重复调用(钻石继承,也叫菱形继承问题)等 MRO MRO即method resolution order,用于判断子类调用的属性来自于哪个父类.在 ...

  4. 深入super,看Python如何解决钻石继承难题

    1.   Python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通方法和super方法 假设Base是基类 class Base(object): def __init_ ...

  5. 《JAVA程序设计与实例》记录与归纳--继承与多态

    继承与多态 概念贴士: 1. 继承,即是在已经存在的类的基础上再进行扩展,从而产生新的类.已经存在的类成为父类.超类和基类,而新产生的类成为子类或派生类. 2. Java继承是使用已存在的类的定义作为 ...

  6. Python中类的__init__继承

    Python中类的__init__继承 概念: 定义父类 In [10]: class Person: ....: def __init__(self,name,age,sex): ....: sel ...

  7. Python设计模式 - 基础 - 封装 & 继承 & 多态

    面向对象的核心是对象,世间万物都可以看作对象,任何一个对象都可以通过一系列属性和行为来描述,可以包含任意数量和类型的数据或操作.类是用来描述具有相同属性和方法的所有对象的集合.类通常是抽象化的概念,而 ...

  8. 【学习笔记】--- 老男孩学Python,day18 面向对象------继承

    继承 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类, 父类又可称为基类或超类,新建的类称为派生类或子类 python中类的继承分为:单继承和多继承 class Fathe ...

  9. python之面向对象(继承)

    类的继承 python之面向对象(继承) 面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制.继承完全可以理解成类之间的类型和子类型关系. 需要注意的地方:继承语法 c ...

随机推荐

  1. S.M.A.R.T.记录几块ssd硬盘

    1.闪迪至尊超级速(Extreme pro) 2.三星sm961 (m2接口) 3.intel 750 (pice接口) ps: 因为sm961,intel750都是nvme协议,网上大部分软件测试都 ...

  2. sonarqube中new issue的标准

    https://docs.sonarqube.org/latest/user-guide/issues/#header-4 Understanding which Issues are "N ...

  3. How to resize slide dimensions without resizing any objects on the slide?

    IF you are competent to unzip the pptx file and modify the XML it can be done, the slide size will c ...

  4. c#判断DatagridView表里是否有某个字段

    if (DatagridView.Columns.Contains("旧ID"))                {                   有             ...

  5. Paper Reading: In Defense of the Triplet Loss for Person Re-Identification

    In Defense of the Triplet Loss for Person Re-Identification  2017-07-02  14:04:20   This blog comes ...

  6. $on在构造器外部添加事件(通过$emit进行外部调用)$once执行一次的事件(通过$emit进行外部调用)$off关闭事件

    $on 在构造器外部添加事件. $on接收两个参数,第一个参数是调用时的事件名称,第二个参数是一个匿名方法. 如果按钮在作用域外部,可以利用$emit来执行. html <div id=&quo ...

  7. postgreSql——时区问题

    timestamptz.timestamp SELECT ts AT TIME ZONE 'UTC' FROM ( VALUES (timestamptz '2012-03-05 17:00:00+0 ...

  8. 解决 dpkg: warning: files list file for package 'x' missing 问题

    参考: dpkg: warning: files list file for package 'x' missing 解决 dpkg: warning: files list file for pac ...

  9. TortoiseGit自动记住用户名密码的方法

    TortoiseGit自动记住用户名密码的方法 windows下比较比较好用的git客户端有2种: msysgit + TortoiseGit(乌龟git) GitHub for Windows gi ...

  10. python Exception raise

    异常是指程序中的例外,违例情况.异常机制是指程序出现错误后,程序的处理方法.当出现错误后,程序的执行流程发生改变,程序的控制权转移到异常处理.Exception类是常用的异常类,该类包括Standar ...