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 ...
随机推荐
- reshape2
require(reshape2)x = data.frame(subject = c("John", "Mary"), tim ...
- Video Frame Synthesis using Deep Voxel Flow 论文笔记
Video Frame Synthesis using Deep Voxel Flow 论文笔记 arXiv 摘要:本文解决了模拟新的视频帧的问题,要么是现有视频帧之间的插值,要么是紧跟着他们的探索. ...
- Kubernetes之总体了解
Kubernetes:架构.基本概念.用于总体了解 Kubernetes系列之介绍篇:优势.用途 Kubernetes核心概念总结
- java泛型的作用和好处
转载于:https://blog.csdn.net/u012760183/article/details/52092692 之前参加面试的时候遇到面试官问泛型的作用,只是说了大概自己的理解, 在此转载 ...
- node.js 学习笔记一
2017-05-01 安装node 我没安装,下载即使用.要全局使用的话把node加入到环境变量中即可. 以下命令环境均为 cmd . 体验 体验一: 在命令行输入 node ,即进入 node 程序 ...
- [0413] FFTSHIFT的四种写法
FFTSHIFT的四种写法 前言 matlab说,"你读过书,--我便考你一考.fftshift的函数,怎样写的?"我想,讨饭一样的人,也配考我么?便回过脸去,不再理会.matla ...
- HDU 5988 Coding Contest(浮点数费用流)
http://acm.split.hdu.edu.cn/showproblem.php?pid=5988 题意:在acm比赛的时候有多个桌子,桌子与桌子之间都有线路相连,每个桌子上会有一些人和一些食物 ...
- jsTree使用
引用:jsTreede css 与Js 初始化jsTree: //加载树 function initTree(treeData) { $.jstree.destroy(); $('#treeDiv') ...
- python 加密
https://github.com/duanhongyi/gmssl
- python 读写json文件(dump, load),以及对json格式的数据处理(dumps, loads)
JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式.它基于ECMAScript的一个子集. 1.json.dumps()和json.loads()是json ...