Python基础13_类与类型, MRO, C3算法, super()

一. python多继承  类与类型:http://www.cnblogs.com/blackmatrix/p/5594109.html

子类继承了多个父类, 当父类出现了重名方法时, 这时就涉及到查找父类方法的问题, 即MRO(method resolution order)问题

python中有两种类, 经典类和新式类

在Python2及以前的版本中,由任意内置类型派生出的类(只要一个内置类型位于类树的某个位置),都属于“新式类”,都会获得所有“新式类”的特性;反之,即不由任意内置类型派生出的类,则称之为“经典类”。

“新式类”和“经典类”的区分在Python3之后就已经不存在,在Python3.x之后的版本,因为所有的类都派生自内置类型object(即使没有显示的继承object类型),即所有的类都是“新式类”。

主要是在多重继承时才会区分二者。

二. 经典类的MRO

经典类的继承是深度优先遍历,即从下往上搜索;

所有经典类的代码必须在Python2下运行

三. 新式类的MRO  官网C3算法解释: https://www.python.org/download/releases/2.3/mro/

新式类的继承顺序是采用C3算法(非广度优先, 广度优先是按层级关系逐层遍历)

方法中有super()才用得着MRO

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 G(E):

pass

class H(G, F):

pass

(1).分拆

首先. 我们要确定从H开始找. 也就是说. 创建的是H的对象.

如果从H找. 那找到H的父类的C3, 我们设C3算法是L(x) , 即给出x类. 找到x的MRO

L(H) = H + L(G) + L(F) + GF

继续从代码中找G和F的父类往里面带

L(G) = G + L(E) + E

L(F) = F + L(D)+ L(E) + DE

继续找E 和 D

L(E) = E + L(C) + L(A) + CA

L(D) = D + L(B) + L(C) + BC

继续找B和C

L(B) = B + L(A) + A

L(C) = C + L(A) + A

(2).合并

最后就剩下?一个A了了. 也就不用再找了了. 接下来. 把L(A) 往里带. 再推回去. 但要记住. 这里的 + 表示的是merge. merge的原则是用每个元组的头?一项和后面元组的除头一项外的其他元素进行比较, 看是否存在. 如果存在. 就从下一个元组的头一项继续找. 如果找不到. 就拿出来. 作为merge的结果的一项. 以此类推. 直到元组之间的元素都相同. 也就不用再找了了.

L(B) =(B,) + (A,) + (A) -> (B, A)

L(C) =(C,) + (A,) + (A) -> (C, A)

继续带.

L(E) = (E,) + (C, A) + (A) + (C,A) -> E, C, A

L(D) = (D,) + (B, A) + (C, A) + (B, C) -> D, B, C, A

继续带.

L(G) = (G,) + (E, C, A) + (E) -> G, E, C, A

L(F) = (F,) + (D, B, C, A) + (E, C, A) + (D, E)-> F, D, B, E, C, A

加油, 最后了

L(H) = (H, ) + (G, E, C, A) + ( F, D, B, E, C, A) + (G, F) -> H, G, F, D, B, E, C, A

算完了. 最终结果 HGFDBECA. 那这个算完了. 如何验证呢? 其实python早就给你准备好了. 我们可以使用类名.__mro__获取到类的MRO信息.

print(H.__mro__)

结果:

(<class ‘__main__.H‘>, <class ‘__main__.G‘>, <class ‘__main__.F‘>, <class ‘__main__.D‘>, <class ‘__main__.B‘>, <class ‘__main__.E‘>, <class ‘__main__.C‘>,<class ‘__main__.A‘>, <class ‘object‘>)

结果OK. 那既然python提供了. 为什么我们还要如此麻烦的计算MRO呢? 因为笔试.......你在笔试的时候, 是没有电脑的. 所以这个算法要知道. 并且简单的计算要会. 真是项?开发的时候很少有人这么去写代码.

四. super()

super()帮我们执行MRO中下一个父类的方法, 通常super()有两个使用的地方

1. 可以访问父类的构造方法, 简化了子类的书写

2. 当子类方法想调用父类MRO中的方法

super(cls, self).func() 执行cls类的MRO中下一个类的func方法

super().func()    执行当前类的MRO中下一个类的func方法

原文地址:https://www.cnblogs.com/guyannanfei/p/10169840.html

时间: 2024-10-08 13:01:32

Python基础13_类与类型, MRO, C3算法, super()的相关文章

python的继承,多继承,经典类的MRO,新式类的MRO,C3算法,super

#继承 class JiaoFu: def qd(self): print("教父带你祈祷") class Fu: def msj(self): print("alex喜欢msj") class Zi(Fu, JiaoFu): def dbj(self): print("刘伟喜欢大宝剑") z = Zi() z.msj() z.dbj() z.qd() class Base1: # Base1 object def func(self): pri

Python基础之一:文件类型及运算符

一.PYTHON文件类型 1.源代码 Python源代码的文件以"py"为扩展名,由Python解释,不需要编译: 2.字节代码 Python源文件经编译后生成的扩展名为"pyc"的文件: 编译方法:     importpy_compile     py_compile.compile("hello world.py") 3.优化代码 经过优化的源文件,扩展名为".pyo"  python –O –m py_compile 

mro c3算法

1了解python2和python3类的区别 python2在2.4之前使用的是经典类, 2.4之后, 使用的是新式类 class Foo: pass class Foo(object): pass MRO: method resolution order 方法的查找顺序 class Base: pass class Base1: def chi(): pass class Bar(Base, Base1): pass b = Bar() # Bar -> Base -> Base1 b.ch

21 MRO C3算法

三十九 MRO 多继承的继承顺序 一.python2.2之前用的是   经典类的MRO继承 ①深度递归继承     从左到右 ,一条路走到黑 ②广度继承           一层一层的继承 深度继承时   为   R 1 2 3 4 5 6 广度继承时  为    R 1 4 2 3  5 6 二.python2.2 之后用的是      新式的MRO继承    C3算法 1.拆分 2.合并 拆分 合并 直接打印时 三.  super( ).方法          找MRO  顺序的下一项 su

python基础巩固(变量类型:字典、集合、元组、列表、数字、字符串)

Python 3 教程 菜鸟教程 https://www.runoob.com/python3/python3-tutorial.html 在控制台DOS运行.py文件 先切换到.py文件所在目录 再输入python hello.py (输入python3 hello.py执行会报错,这里与菜鸟教程不同) 在Unix & Linux 平台安装 Python3 先下载Unix/Linux的源码压缩包 https://www.python.org/downloads/source/ 解压压缩包,并安

Python基础(十一) 类继承

类继承: 继承的想法在于,充份利用已有类的功能,在其基础上来扩展来定义新的类. Parent Class(父类) 与 Child Class(子类): 被继承的类称为父类,继承的类称为子类,一个父类,可以有多个子类: 子类,一旦继承父类,就拥有了父类的属性与方法,根据需要可以进行增删改. 这种做法的主要好处之一就是代码重用. 示例代码1: #*_*coding:utf-8*_* class perent_class(object): def __init__(self,name): self.n

python基础===新式类与经典类

首先: Python 2.x中默认都是经典类,只有显式继承了object才是新式类 Python 3.x中默认都是新式类,不必显式的继承object 这两种类的区别: 新式类重定义的方法更多,当然这不是重点,重点是两种类在多继承状态下查找"方法"的规则不同. 经典类: 深度查找 显示类:广度查找 其次: ------新式类对象可以直接通过__class__属性获取自身类型:type ------继承搜索的顺序发生了改变,经典类多继承属性搜索顺序: 先深入继承树左侧,再返回,开始找右侧;

Python基础知识之基本类型、循环

1.python基本类型有:数字.字符串.列表.元组.字典. (1)数字类型有如下类型: int(有符号整型)   long(长整型[也可以代表八进制和十六进制])   float(浮点型)   complex(复数) (2)字符串:字符串或串(String)是由数字.字母.下划线组成的一串字符. (3)列表:列表是最常用的Python数据类型,它可以作为一个方括号内的逗号分隔值出现. (4)元组:Python的元组与列表类似,不同之处在于元组的元素不能修改.元组使用小括号,列表使用方括号. (

python基础复习-1-1文件类型、变量、运算符、表达式

文件类型: .py python源文件 由python解释器执行 .pyc python源码编译后生成的文件(字节代码) 编译方法: 源码文件中使用py_compile模块 import py_compile py_complie.compile('***.py') .pyo python源码优化编译后后文件 python -O -m compile ***.py (无需要源码中使用 compile模块) -O 表示优化 -m 表示模块 python 变量 变量是计算机内存中的一个区域,可以存储