核能来袭 --MRO和C3算法

1. python的多继承

2.python经典类的MRO

3.python新式类的MRO, C3算法

4.super 是什么鬼?

一.python的多继承

在前面的学习过程中,我们已经知道了python中类与类之间可以有继承关系,当出现了x是一种y的时候,局可以使用继承关系.在继承关系中,子类自动拥有父类除了私有属性外的其他所有的内容,python支持多继承.一个类可以拥有多个父类.

  1. class ShenXian: #神仙
  2. def fei(self):
  3. print('神仙都会飞')
  4.  
  5. class Monkey: #猴
  6. def chitao(self):
  7. print('猴子喜欢吃桃子')
  8.  
  9. class WuKong(shenxian,Monkey): # 孙悟空
  10. pass
  11.  
  12. qtds=WuKong() #齐天大圣
  13. qtds.chitao() # 吃桃
  14. qtds.fei() # 飞

多继承用起来很简单,也很好理解,但是如果2个父类中出现重名方法时,这时就出现了查找顺序的问题,即MRO问题:

在python2中存在2 类,经典类,新式类(注意:树形结构图和C3算法算出来的结果不一定是相同的)

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

  新式类:在python2.2之后出现了新式类,特点是基类的根是object

在python3中,

  都是新式类,如果基类谁都不继承,那么这个类默认继承object

二 . python经典类的MRO

虽然python3中不存在经典类了,但还是要学一学,经典类是一种树形结构遍历的一个最直接的案例,在python继承体系中,我们可以把类与类继承关系化成一个树形结构图,

  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.

三.新式类的MRO

Python个中的新式类的MRO是采用C3算法来完成的

C3算法其实很简单,只要看代码就可以了,不需要去画图,

  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开始找:(从下往上找),也就是说,创建的是H的对象.

设C3算法是L(x),找到x对的MRO,即:

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

继续从父类中往上找

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

(注:加法,merge(),拿第一项的第一位与后面每项中除了第一位比较,如果没出现,算出这一位(算出后所有的这一个字母全部删除),继续拿这一位的下一位重复上面的操作;如果出现了,此时开始下一项的第一位继续跟后面每一项的出了第一位比较)  

这个说完了,C3到底怎么看更容易呢,其实很简单,C3是把我们多个类产生的共同继承留到最后去找,所以,我们也可以从图上来看到相关的规律,这个要大家自己多写多画就能感觉到了,但是如果没有所谓的共同继承关系,那几乎就当成是深度遍历就可以了.

四.super是什么鬼?

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

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)

结论: 不管super()写在哪里,在哪执行.一定先找到MRO列表,根据MRO列表的顺序往下找,否则一切都是错的 

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

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

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

  2. Python之MRO及其C3算法

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

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

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

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

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

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

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

  6. python之MRO和C3算法

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

  7. MRO和C3算法

    本节主要内容: 1.python多继承 2.python经典类的MRO 3.python新式类的MRO,C3算法 4.super() 一.python多继承 在python中类与类之间可以有继承关系, ...

  8. python MRO及c3算法

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

  9. python中的MRO和C3算法

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

随机推荐

  1. 猫眼电影爬取(二):requests+beautifulsoup,并将数据存储到mysql数据库

    上一篇通过requests+正则爬取了猫眼电影榜单,这次通过requests+beautifulsoup再爬取一次(其实这个网站更适合使用beautifulsoup库爬取) 1.先分析网页源码 可以看 ...

  2. USBCAN的使用和上位机开发(MFC)

    USBCAN使用手册 参见:https://blog.51cto.com/12572800/2062839 1. USB CAN软件安装与硬件接线 USB CAN是常用的CAN测试工具.它的软件资料存 ...

  3. ubuntu16.04安装LCM

    1.sudo apt-get install build-essential autoconf automake autopoint libglib2.0-dev libtool openjdk-8- ...

  4. 分享基于EF+WCF的通用三层架构及解析

    本项目结合EF 4.3及WCF实现了经典三层架构,各层面向接口,WCF实现SOA,Repository封装调用,在此基础上实现了WCFContext,动态服务调用及一个分页的实例. 1. 项目架构图: ...

  5. LeetCode--020--括号匹配

    题目描述: 给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效. 有效字符串需满足: 左括号必须用相同类型的右括号闭合. 左括号必须以正确的顺序闭合. 注意空 ...

  6. CSS之透视perspective属性

    透视原理: 近大远小 . 浏览器透视:把近大远小的所有图像,透视在屏幕上. 书写方式不同的定义 perspective有两种定义方式,如下 .class{ perspective: 800px; } ...

  7. Nim or not Nim? HDU - 3032

    题意:给定n堆石子,两人轮流操作,每次选一堆石子,取任意石子或则将石子分成两个更小的堆(非0),取得最后一个石子的为胜. 题解:比较裸的SG定理,用sg定理打表,得到表1,2,4,3,5,6,8,7, ...

  8. python基础之函数参数,名称空间,以及函数嵌套

    函数进阶内容梗概: 1. 函数参数--动态传参 2. 名称空间, 局部名称空间, 全局名称空间, 作⽤用域, 加载顺序. 3. 函数的嵌套 4. gloabal , nonlocal 关键字 1. 函 ...

  9. loj#2020. 「AHOI / HNOI2017」礼物

    题意:给定xy数组求 \(\sum_{i=0}^{n-1}(x_i+y_{(i+k)\modn}+c)^2\) 题解:先化简可得 \(n*c^2+2*\sum_{i=0}^{n-1}x_i-y_i+\ ...

  10. Oracle 基本操作--数据类型、修改和删除表、增删改查和复制表

    一.Oracle基础数据类型:数据类型: 创建数据表时,设计数据表的结构问题,也就是设计及确定数据表中各个列的数据类型,是数值.字符.日期还是图像等其他类型. 因为只有设计好数据表结构,系统才会在磁盘 ...