python记录day_20 多继承
多继承
继承: 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 多继承的更多相关文章
- 深入super,看Python如何解决钻石继承难题 【转】
原文地址 http://www.cnblogs.com/testview/p/4651198.html 1. Python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通 ...
- python作用域和多继承
python作用域 python无块级作用域 看c语言代码: #include<stdio.h> int main() { > ) { ; } printf("i = %d ...
- python中使用多继承
python中使用多继承,会涉及到查找顺序(MRO).重复调用(钻石继承,也叫菱形继承问题)等 MRO MRO即method resolution order,用于判断子类调用的属性来自于哪个父类.在 ...
- 深入super,看Python如何解决钻石继承难题
1. Python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通方法和super方法 假设Base是基类 class Base(object): def __init_ ...
- 《JAVA程序设计与实例》记录与归纳--继承与多态
继承与多态 概念贴士: 1. 继承,即是在已经存在的类的基础上再进行扩展,从而产生新的类.已经存在的类成为父类.超类和基类,而新产生的类成为子类或派生类. 2. Java继承是使用已存在的类的定义作为 ...
- Python中类的__init__继承
Python中类的__init__继承 概念: 定义父类 In [10]: class Person: ....: def __init__(self,name,age,sex): ....: sel ...
- Python设计模式 - 基础 - 封装 & 继承 & 多态
面向对象的核心是对象,世间万物都可以看作对象,任何一个对象都可以通过一系列属性和行为来描述,可以包含任意数量和类型的数据或操作.类是用来描述具有相同属性和方法的所有对象的集合.类通常是抽象化的概念,而 ...
- 【学习笔记】--- 老男孩学Python,day18 面向对象------继承
继承 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类, 父类又可称为基类或超类,新建的类称为派生类或子类 python中类的继承分为:单继承和多继承 class Fathe ...
- python之面向对象(继承)
类的继承 python之面向对象(继承) 面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制.继承完全可以理解成类之间的类型和子类型关系. 需要注意的地方:继承语法 c ...
随机推荐
- 【命令】MongoDB常用命令记录
如果你想创建一个“myTest”的数据库,先运行use myTest命令,之后就做一些操作(如:db.createCollection('user')),这样就可以创建一个名叫“myTest”的数据库 ...
- P3975 [TJOI2015]弦论
思路 一眼SAM板子,结果敲了一中午... 我还是太弱了 题目要求求第k小的子串 我们可以把t=0当成t=1的特殊情况,(所有不同位置的相同子串算作一个就是相当于把所有子串的出现位置个数(endpos ...
- Docker7之Docker overview
Docker is an open platform for developing, shipping, and running applications. Docker enables you to ...
- 操作 frames 框架下的 dom 内容。
2016-12-30 框架名: var obj=$(window.frames["wangpan"].document).find("a[menu=download_on ...
- R语言可视化学习笔记之ggpubr包—SCI文章图
转载:https://www.jianshu.com/p/678213d605a5?from=jiantop.com Hadley Wickham创建的可视化包ggplot2可以流畅地进行优美的可视化 ...
- JaveWeb 公司项目(1)----- 使Div覆盖另一个Div完成切换效果
最近在做网页,用的是CSS+DIV的布局方法,搭建了一个简易的界面,大体上分为三个部分,如图所示: 左侧的为主功能导航栏,右侧是具体的功能实现,下方是固定的版权声明,单击左边不同的导航按钮,在div中 ...
- 远程连接MySQL MySQL的远程连接
在笔记本上安装了mysql, 想测试一下连接池对性能的影响,用了另一台PC来测试一段sql,出现以下错误: jdbc:mysql://10.201.11.128:3306/test Cannot cr ...
- maven阿里云镜像及本地仓库
一.添加阿里云镜像 1 找到maven的安装目录,conf文件夹下的setting.xml文件 2 打开setting.xml文件,找到mirrors节点添加阿里镜像库地址: <mirror&g ...
- libxml2_ZC积累
1.Qt5.3.2(VS2010 OpenGL) 1.1.查找节点的 带NameSpace的属性 参考网址:https://stackoverflow.com/questions/7872413/ho ...
- UT, FT ,E2E 测试的意思
前端实现自动化就要借助到unit和e2e端到端测试了 一.unit测试(FT 就是Fucntion Test 功能测试, 注意不是: funciton函数 ...fucntion功能 不一样哦 ...