1、新式类

在 py3 里面的继承 object 的类,以及它的子类都是新式类

多继承的情况下,会按照广度优先的方式查找

为什么调用父类

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class A:   # 默认继承 object类def __init__(self):print("enter A")print("leave A")
class B(A):def __init__(self):print("enter B")super(B, self).__init__()print("leave B")b = B()
enter B
enter A
leave A
leave B通过调用super获得父类实例从而可以实现该实例的初始化函数.  (因为要继承父类的功能, 又要有新的功能).
直接使用父类来调用的差异

事实上, 上面的super函数方法还可以这么写:

class A:def __init__(self):print("enter A")print("leave A")
class B(A):def __init__(self):print("enter B")A.__init__(self)print("leave B")

通过直接使用父类类名来调用父类的方法, 实际也是可行的. 起码在上面的例子中效果上他们现在是一样的. 这种方法在老式类中也是唯一的调用父类的方法 (老式类没有super).

通过父类类名调用方法很常用, 比较直观. 但其效果和super还是有差异的. 例如:

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class A:def __init__(self):print("enter A")print("leave A")
class B(A):def __init__(self):print ("enter B")A.__init__(self)print "leave B")
class C(A):def __init__(self):print("enter C")A.__init__(self)print("leave C")
class D(B,C):def __init__(self):print("enter D")B.__init__(self)C.__init__(self)print("leave D")
>>> d=D()
enter D
enter B
enter A
leave A
leave B
enter C
enter A
leave A
leave C
leave D

可以发现, 这里面A的初始化函数被执行了两次. 因为我们同时要实现B和C的初始化函数, 所以分开调用两次, 这是必然的结果.

但如果改写成super呢?

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class A:def __init__(self):print ("enter A")print ("leave A")
class B(A):def __init__(self):print ("enter B")super().__init__()print ("leave B")
class C(A):def __init__(self):print ("enter C")super().__init__()print ("leave C")
class D(B,C):def __init__(self):print ("enter D"super().__init__()print ("leave D"
>>> d=D()
enter D
enter B
enter C
enter A
leave A
leave C
leave B
leave D

会发现所有父类ABC只执行了一次, 并不像之前那样执行了两次A的初始化.

然后, 又发现一个很奇怪的: 父类的执行是 BCA 的顺序并且是全进入后再统一出去.

如果没有多继承,super其实和通过父类来调用方法差不多. 但, super还有个好处: 当B继承自A, 写成了A.init, 如果根据需要进行重构,继承 class A 全部要改成继承自 E,那么全部都得改一次! 这样很麻烦而且容易出错! 而使用super()就不用一个一个改了(只需子类继承父类,定义中改一改就好了)

2、MRO表

MRO是什么? 可以通过以下方式调出来:

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
>>> D.mro() # or d.__class__.mro()  or D.__class__.mro(D)
[D, B, C, A, object]
>>> B.mro()
[B, A, object]
>>> help(D.mro)
#Docstring:
#mro() -> list
#return a type's method resolution order
#Type:      method_descriptor

MRO就是类的方法解析顺序表, 其实也就是继承父类方法时的顺序表 (类继承顺序表去理解也行) 啦.

这个表有啥用? 首先了解实际super做了啥:

def super(cls, inst):mro = inst.__class__.mro()return mro[mro.index(cls) + 1]

换而言之, super方法实际是调用了cls的在MRO表中的下一个类. 如果是简单一条线的单继承, 那就是父类->父类一个一个地下去罗. 但对于多继承, 就要遵循MRO表中的顺序了. 以上面的D的调用为例:

d的初始化
-> D (进入D) super(D,self)
-> 父类B (进入B) super(B,self)
-> 父类C (进入C) super(C,self)
-> 父父类A (进入A)  (退出A) # 如有继续super(A,self)  -> object (停了)
-> (退出C)
-> (退出B)
-> (退出D)

所以, 在MRO表中的超类初始化函数只执行了一次!

在 MRO 中,基类永远出现在派生类后面,如果有多个基类,基类的相对顺序保持不变。

这个原则包括两点:

  1. ​ 基类永远在派生类后面
  2. ​ 类定义时的继承顺序影响相对顺序.

如果有以下继承

那么MRO是: F -> E -> B -> C -> D -> A -> object

  • 先找出最长深度最深的继承路线F->E->C->A->object. (因为必然基类永远出现在派生类后面)

  • 类似深度优先, 定出其余顺序: F->E->B->obj, F->D->A-object

  • 如果有多个基类,基类的相对顺序保持不变, 类似于merge时优先提前面的项. 所以排好这些路线: (FEBO, FECAO, FDAO)

  • F->E->B->obj且E(B,C)决定B在C前面.所以F->E->B->C->A->obj (相当于F+merge(EBO,ECAO)).

  • F->D->A-object且F(E,D)决定了D在E后, 所以D在E后A前. 因为相对顺序, 相当于FE+merge(BCAO, DAO), 所以FE BC D AO

Python基础教程:新式类与经典类相关推荐

  1. Python基础教程:类的property特性

    一.什么是 property特性 property装饰器用于将被装饰的方法伪装成一个数据属性,在使用时可以不用加括号而直接使用 # ############### 定义 ############### ...

  2. python中新式类和经典类

    python中的类分为新式类和经典类,具体有什么区别呢?简单的说, 1.新式类都从object继承,经典类不需要. Python 2.x中默认都是经典类,只有显式继承了object才是新式类 Pyth ...

  3. python新式类和经典类区别_Python中新式类和经典类的区别,钻石继承

    1)首先,写法不一样: class A: pass class B(object): 2)在多继承中,新式类采用广度优先搜索,而旧式类是采用深度优先搜索. 3)新式类更符合OOP编程思想,统一了pyt ...

  4. python中的__new__与__init__,新式类和经典类(2.x)

    在python2.x中,从object继承得来的类称为新式类(如class A(object))不从object继承得来的类称为经典类(如class A()) 新式类跟经典类的差别主要是以下几点: 1 ...

  5. python新式类和经典类的区别?

    在python里凡是继承了object的类,都是新式类. Python2里面继承object的是新式类,没有写父类的是经典类. Python3里只有新式类. 经典类目前在Python里基本没有应用,多 ...

  6. Python 新式类与经典类

    新式类,经典类 查询匹配 广度查询 横着对每个类进行查询 深度查询 无视平级类,直接寻找下级类 #python 3.0 #新式类 广度查询 #经典类 广度查询 #python 2.0 #新式类 广度查 ...

  7. Python 中的新式类和经典类的区别?

    1. 版本支持 / 写法差异# 在Python 2.x 中 如果你至今使用的还是 Python 2.x,那么你需要了解一下,在Python 2.x中存在着两种类:经典类和新式类. 什么是经典类? Co ...

  8. python经典类新式类_Python的新式类和经典类

    1. 前言 python在2.2版本中引入了descriptor功能,也正是基于这个功能实现了新式类(new-styel class)的对象模型, 同时解决了之前版本中经典类(classic clas ...

  9. python中新式类和经典类的区别

    1.新式类和经典类 在Python 2及以前的版本中,由任意内置类型派生出的类(只要一个内置类型位于类树的某个位置),都属于"新式类",都会获得所有"新式类"的 ...

  10. python新式类和经典类的区别

    python新式类和经典类的区别 1,新式类和经典类的区别: 广度优先和深度优先,这主要是在多类继承的时候会使用到,如下多类继承的D类对比: 经典类在加载的时候采用的是深度优先算法,二新式类采用的是广 ...

最新文章

  1. Android强制设置横屏或竖屏
  2. python 用户认证_Python使用LDAP做用户认证的方法
  3. java不抛出方法异常,java – 重写方法不会抛出异常
  4. 小白入门商业数据分析师的课程测评
  5. php curl 防止采集,php多线程采集网页的解决办法 curl多线程采集
  6. roads 构筑极致用户体验_长安马自达「悦马星空」计划上线,为用户带来极致服务体验...
  7. basicdatasourcefactory mysql_Java基础-DBCP连接池(BasicDataSource类)详解
  8. C#读书笔记之继承、接口与抽象类续
  9. ilm 和dlm差异_Oracle 的信息生命周期管理工具(ILM assistant)
  10. windows系统下搭建私有nuget仓储服务器, 打包程序集并推送到私有nuget仓储服务器...
  11. 火狐浏览器安装印象笔记剪藏
  12. 2022-2028全球新冠检测试剂行业调研及趋势分析报告
  13. pb导入excel文件
  14. 按键精灵-UI配置丢失问题解决办法
  15. P4379 [USACO18OPEN]Lemonade Line
  16. 多线程:转载自-时光如水_岁月如哥
  17. 51单片机~光敏传感器,比较器(模电,运放,放大原理)原理芯片
  18. 统计推断——假设检验——两变量关联性分析
  19. Jeesite七个文件作用解释
  20. 排序算法详解(Java实现 + 动画演示)

热门文章

  1. 大数阶乘的位数和精确值计算
  2. HUT-1556 网址
  3. hyper-V环境下虚拟机和宿主机之间时钟不统一
  4. spark代码连接hive_Spark SQL入门到实战之(7)spark连接hive(spark-shell和eclipse两种方式)...
  5. malloc 结构体_算法与数据结构——结构体变量
  6. 【VC基础】 5、对象相关性(Object Dependencies)
  7. SAP HR模块的基础数据表和增强配置
  8. SAP存货后续调整总结
  9. 如何导出SAP的数据表字段和字段描述
  10. abap 调用外部web service 使用小结