一. 经典类和新式类

1.python多继承

  在继承关系中,python子类自动用友父类中除了私有属性外的其他所有内容.python支持多继承.一个类可以拥有多个父类

2.python2和python3的区别

  python2中存在两种类,一个叫经典类,在python2.2之前,一直使用的经典类.经典类是在基类的根如果什么都不写.表示继承xxx

另一个叫做心事类,在python2.2之后出现了心事类.新式类的特点是基类的根是object

  python3中使用的都是新式类.如果基类谁都不继承,那这个类会默认继承object

二. 经典类的MRO

python早就为我们准备好了查看MRO的方法.可以使用类名.__mro__获取到累的MRO信息

  1. 经典类的MRO  树型结构的深度优先遍历  -->   树形结构遍历

  1. class Foo:
  2. pass
  3.  
  4. class Foo(object):
  5. pass
  6.  
  7. MRO: method resolution order 方法的查找顺序
  8.  
  9. class Base:
  10. pass
  11.  
  12. class Base1:
  13. def chi():
  14. pass
  15.  
  16. class Bar(Base, Base1):
  17. pass
  18.  
  19. b = Bar() # Bar -> Base -> Base1
  20. b.chi()

  再举一个例子

  1. class A:
  2. pass
  3. class B(A):
  4. pass
  5. class C(A):
  6. pass
  7. class D(B, C):
  8. pass
  9. class E:
  10. pass
  11. class F(D, E):
  12. pass
  13. class G(F, D):
  14. pass
  15. class H:
  16. pass
  17. class Foo(H, G):
  18. pass

  来看关系图

进行深度优先遍历

MRO: Foo-> H -> G -> F -> D -> B -> A -> C -> E.

2. 新式类的MRO  C3算法

  1. C3方法解决顺序
    让我介绍几个简单的符号,这些符号对以下讨论很有用。我将使用快捷方式表示法
  2.  
  3. C1 C2 ... CN
    表示类别列表[C1C2,...,CN]。
  4.  
  5. 列表的头部是它的第一个元素:
  6.  
  7. head = C1
    而尾巴是列表的其余部分:
  8.  
  9. tail = C2 ... CN
    我也会用这个符号
  10.  
  11. C +(C1 C2 ... CN)= C C1 C2 ... CN
    表示列表的总和[C] + [C1C2,...,CN]。
  12.  
  13. 现在我可以解释MRO如何在Python 2.3中运行。
  14.  
  15. 考虑多继承层次结构中的C类,其中C继承自基类B1B2,...,BN。我们想要计算C类的线性化L [C]。规则如下:
  16.  
  17. C的线性化是C的总和加上父母的线性化和父母的列表的合并。
    用符号表示法:
  18.  
  19. L [CB1 ... BN)] = C +合并(L [B1] ... L [BN],B1 ... BN
    特别是,如果C是没有父项的对象类,则线性化是微不足道的:
  20.  
  21. L [object] =对象。
    但是,通常必须根据以下处方计算合并:
  22.  
  23. 取第一个列表的头部,即L [B1] [0]; 如果这个头不在任何其他列表的尾部,那么将它添加到C的线性化并将其从合并中的列表中删除,否则查看下一个列表的头部并将其取出,如果它是好头。然后重复操作,直到所有课程都被移除或者找不到好头。在这种情况下,不可能构造合并,Python 2.3将拒绝创建类C并将引发异常。
    如果可以保留排序,则此处方确保合并操作保留排序。另一方面,如果无法保留订单(如上面讨论的严重订单不一致的例子),则无法计算合并。
  24.  
  25. 如果C只有一个父(单继承),那么合并的计算是微不足道的。在这种情况下
  26.  
  27. L [CB)] = C +合并(L [B],B)= C + L [B]

官网解释 https://www.python.org/download/releases/2.3/mro/

举例说明

  1. class A:
  2. pass
  3. class B(A):
  4. pass
  5. class C(A):
  6. pass
  7. class D(B, C):
  8. pass
  9. class E(C, A):
  10. pass
  11. class F(D, E):
  12. pass
  13. class G(E):
  14. pass
  15. class H(G, F):
  16. pass

  

首先确定的是要找的H

把每个类转换为C3算法的形式

L(A) = A

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

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

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

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

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

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

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

之后我们来化简

加法:merge(), 拿第一项的第一位和 后面每项的除了第一位比较. 如果没有出现, 则该位元素算出
如果出现了. 此时开始下一项的第一位继续和后面每一项的除了第一位比较:

L(A) = A

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

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

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

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

L(F) = F + L(D) + L(E) + DE = F + DBCA + ECA = FDBECA

L(G) = G + L(E) + E = G +ECA + E = GECA

L(H) = H + L(G) + L(F) + GF = H + GECA + FDBECA + GF = HGFDBECA

三. super

  super() 找MRO顺序的下一个,通常有两个使用的地方:

1.可以访问父类的构造方法

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

  来看一道面试题

  1. # MRO + super ⾯面试题
  2. class Init(object):
  3. def __init__(self, v):
  4. print("init")
  5. self.val = v
  6. class Add2(Init):
  7. def __init__(self, val):
  8. print("Add2")
  9. super(Add2, self).__init__(val)
  10. print(self.val)
  11. self.val += 2
  12. class Mult(Init):
  13. def __init__(self, val):
  14. print("Mult")
  15. super(Mult, self).__init__(val)
  16. self.val *= 5
  17. class HaHa(Init):
  18. def __init__(self, val):
  19. print("哈哈")
  20. super(HaHa, self).__init__(val)
  21. self.val /= 5
  22. class Pro(Add2,Mult,HaHa): #
  23. pass
  24. class Incr(Pro):
  25. def __init__(self, val):
  26. super(Incr, self).__init__(val)
  27. self.val+= 1
  28. # Incr Pro Add2 Mult HaHa Init
  29. p = Incr(5)
  30. print(p.val)
  31. c = Add2(2)
  32. print(c.val)

  

先算出MRO

L(Init) = Init

L(Add2) =Add2 +  L(Init) + Init = Add2 , Init

L(Mult) = Mult + L(Init) + Init = Mult ,Init

L(HaHa) = HaHa + L(Init) + Init = HaHa,Init

L(Pro) = Pro +L(Add2) + L(Mult) + L(HaHa) + Add2,Mult,HaHa = Pro + Add2 , Init + Mult ,Init + HaHa,Init + Add2,Mult,HaHa = Pro,Add2,Mult,HaHa,Init

再进行运算

python中的MRO和C3算法的更多相关文章

  1. python之路--MRO和C3算法

    一 . MRO(method resolution order) 多继承的一种方法,一种查找的顺序 在python3 里面是一种新类式MRO 需要用都的是C3算法 class A: pass clas ...

  2. Python的多继承问题-MRO和C3算法

    大部分内容转载自C3 线性化算法与 MRO 理解Python中的多继承 Python 中的方法解析顺序(Method Resolution Order, MRO)定义了多继承存在时 Python 解释 ...

  3. day21 MRO和C3算法

    核能来袭 --MRO和C3算法 1. python的多继承 2.python经典类的MRO 3.python新式类的MRO, C3算法 4.super 是什么鬼? 一.python的多继承 在前面的学 ...

  4. Python之MRO及其C3算法

    [<class '__main__.B'>, <class '__main__.A'>, <class 'object'>] (<class '__main_ ...

  5. python全栈开发day103-python垃圾回收机制、mro和c3算法解析、跨域jsonp\CORS、Content-Type组件

    Python垃圾回收 -- 引用计数 -- Python为每个对象维护一个引用计数 -- 当引用计数为0的 代表这个对象为垃圾 -- 标记清除 -- 解决孤立的循环引用 -- 标记根节点和可达对象 - ...

  6. python之MRO和C3算法

    python2类和python3类的区别pyhon2中才分新式类与经典类,python3中统一都是新式类Python 2.x中默认都是经典类,只有显式继承了object才是新式类python 3.x中 ...

  7. python MRO及c3算法

    1. 了解python2和python3类的区别 python2在2.3之前使用的是经典类, 2.3之后, 使用的是新式类 2. 经典类的MRO 树形结构的深度优先遍历 -> 树形结构遍历 cl ...

  8. python摸爬滚打之day20--多继承,MRO和C3算法

    1.新式类和经典类 在python2.2之前, 基类如果不写(), 则表示为经典类; 在python2.2之后, 经典类不复存在, 只存在新式类. 如果基类谁都不继承的话, 则默认继承object. ...

  9. Python新式类继承的C3算法

    在Python的新式类中,方法解析顺序并非是广度优先的算法,而是采用C3算法,只是在某些情况下,C3算法的结果恰巧符合广度优先算法的结果. 可以通过代码来验证下: class NewStyleClas ...

随机推荐

  1. Rhythmk 学习 Hibernate 06 - Hibernate 表间关系 [One To One]

    1.One To One 单相 背景: 古代一个老婆  只能关联一个老公 husband.java package com.rhythmk.model; public class husband { ...

  2. 横向文本框 index获取索引 和 eq 实现

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. 检测IE浏览器版本是否过低

    <script type="text/javascript"> /*判断浏览器版本是否过低*/ $(document).ready(function() {s var ...

  4. ansible模块学习

    ansible的功能: 模块化任务,调用特定的模块,完成特定的任务 基于python语言实现,由paramiko.pyyaml和jinja2三个模块构建 部署简单,agentless,ansible基 ...

  5. Axure知识点

    1 一个事件包含N个用例:一个用例包含N个动作.

  6. Element DatePicker日期范围选择

    前7天后7天 <el-date-picker v-model="value1" type="date" :picker-options="pic ...

  7. 理解UV贴图

    一.理解UV贴图UVs是驻留在多边形网格顶点上的两维纹理坐标点,它们定义了一个两维纹理坐标系统,称为UV纹理空间,这个空间用U和V两个字母定义坐标轴.用于确定如何将一个纹理图像放置在三维的模型表面.本 ...

  8. asp.net页如何获取母版页控件

    获取母版页的相关内容有两种方法 1 通过findcontrol找控件ID需要在此事件中~因为Page_load中时是先内容页加载然后才是母版页加载 protected void Page_LoadCo ...

  9. Windows Python 2.7环境搭建

    一.安装及修改环境变量 我安装的版本是python-2.7.15.amd64,因为2.7.9之后的版本都会安装好pip.将Python执行文件所在文件夹加入path路径,C:\Python27.将pi ...

  10. Gcc And MakeFile Level1

    简单介绍gcc And make 的使用 基本编译 gcc a.c b.c -o exeName 分步编译 gcc -c a.c -o a.o gcc a.o b.c -o main.o 使用Make ...