一. 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