Python 之 super MRO (没有遇到过适用场景)
WOW!!!
这里wow的是真尼玛绕且没看完,
好困呐,贴上网址,等自己英文好一点再看(https://rhettinger.wordpress.com/2011/05/26/super-considered-super/),,,,
自己的理解:
先上例子:
例1:
class A(object):def __init__(self):print "enter A"print "leave A"class B(object):def __init__(self):print "enter B"print "leave B"class C(A):def __init__(self):print "enter C"super(C, self).__init__()print "leave C"class D(A):def __init__(self):print "enter D"super(D, self).__init__()print "leave D"class E(B, C):def __init__(self):print "enter E"B.__init__(self)C.__init__(self)print "leave E"class F(E, D):def __init__(self):print "enter F"E.__init__(self)D.__init__(self)print "leave F"
输出:
enter Fenter Eenter Bleave Benter Center Denter Aleave Aleave Dleave Cleave Eenter Denter Aleave Aleave Dleave F
按我们对super的理解,从图中可以看出,在调用类C的初始化函数时,应该是调用类A的初始化函数,但事实上却调用了类D的初始化函数。好一个诡异的问题!并且类A和类D的初始化函数被重复调用了2次
这是为什么呢?
super不是简单地调用所谓基类的方法,而是调用MRO中的下一个类的方法,也就是类似于next的方法。
mro中记录了一个类的所有基类的类类型序列。查看mro的记录,发觉包含7个元素,7个类名分别为:F E B C D A object
从而说明了为什么在C.__init__中使用super(C, self).__init__()会调用类D的初始化函数了。
不要一说到 super 就想到父类!super 指的是 MRO 中的下一个类!
MRO & super
Method resolution order是python用来解析方法调用顺序的。MRO对于多重继承中方法调用异常重要。python中有一个内建函数和MRO密切相关——super。具体实现方式,有兴趣可以以后看看。
在 MRO 中,基类永远出现在派生类后面,如果有多个基类,基类的相对顺序保持不变。
super做了什么?
def super(cls, inst):mro = inst.__class__.mro()return mro[mro.index(cls) + 1]
两个参数 cls 和 inst 分别做了两件事:
1. inst 负责生成 MRO 的 list
2. 通过 cls 定位当前 MRO 中的 index, 并返回 mro[index + 1]
super的作用是什么呢?
按名字继承的话,如果子类的父类发生变化时,必须要全部替换名字,比较麻烦;
如果没有复杂的继承结构,super 作用不大。
例2:(没太看懂这货)
class A(object):def __init__(self):print "enter A"super(A, self).__init__() # new 寄几继承寄几是什么鬼?print "leave A"class B(object):def __init__(self):print "enter B"super(B, self).__init__() # newprint "leave B"class C(A):def __init__(self):print "enter C"super(C, self).__init__()print "leave C"class D(A):def __init__(self):print "enter D"super(D, self).__init__()print "leave D"class E(B, C):def __init__(self):print "enter E"super(E, self).__init__() # changeprint "leave E"class F(E, D):def __init__(self):print "enter F"super(F, self).__init__() # changeprint "leave F"
输出:
enter Fenter Eenter Benter Center Denter Aleave Aleave Dleave Cleave Bleave Eleave F
明显地,F的初始化不仅完成了所有的父类的调用,而且保证了每一个父类的初始化函数只调用一次。
那么,总结:
1. super并不是一个函数,是一个类名,形如super(B, self)事实上调用了super类的初始化函数, 产生了一个super对象;
2. super类的初始化函数并没有做什么特殊的操作,只是简单记录了类类型和具体实例;
3. super(B, self).func的调用并不是用于调用当前类的父类的func函数;
4. Python的多继承类是通过mro的方式来保证各个父类的函数被逐一调用,而且保证每个父类函数只调用一次(如果每个类都使用super);
如果类被设计成使用了super,那么所有子类也必须要调用super,否则直接调用会出现重复调用的问题
5. 混用super类和非绑定的函数是一个危险行为,这可能导致应该调用的父类函数没有调用或者一个父类函数被调用多次。(保持一致性。要不全部用类名调用父类,要不就全部用 super,不要一半一半。)
参考:
http://www.cnblogs.com/lovemo1314/archive/2011/05/03/2035005.html(super)
http://blog.csdn.net/rommi/article/details/51058360(MRO)
http://blog.csdn.net/seizef/article/details/5310107(super & MRO)
转载于:https://www.cnblogs.com/pannyvan/p/6135190.html
Python 之 super MRO (没有遇到过适用场景)相关推荐
- Python多继承mro示例
Python多继承mro示例 以下是python方法解析顺序的示例,详细的解释见代码的注释部分. # 1 解释python mro的执行顺序,详见数字序号的顺序 class Base(object): ...
- python基础-super
Super返回的是mro列表中的下一个类 python的super详解(二) 文档解释顺序MRO用于在祖先类中查找属性.每个定义的类,都有一个名为__mro__的属性,他是一个元组. super(ty ...
- python super()方法的作用_详解python的super()的作用和原理
Python中对象方法的定义很怪异,第一个参数一般都命名为self(相当于其它语言的this),用于传递对象本身,而在调用的时候则不必显式传递,系统会自动传递.uz0免费资源网 今天我们介绍的主角是s ...
- python之父去面试-Python面试题之Python的Super方法
当我第一次见到这个super()的时候,我想说,这是啥啊?为什么Python的super看起来这么奇怪呢? super直接指向父类的实例不就得了么?为什么非得搞两个参数? 而且第一个参数还是自己的类名 ...
- Python的Super方法
我们最常见的,可以说几乎唯一能见到的使用super的形式是: class SubClass(BaseClass):def method(self):super(SubClass, self).meth ...
- python3 super_Python super()– Python 3 super()
python3 super Python super() function allows us to refer to the parent class explicitly. It's useful ...
- Python多继承mro
在python语言里是支持继承这一概念的,也就是一个class可以继承一些其他class方法或者数据,在继承的时候有的比较简单,比如下面这段代码就是classM继承了classA class A(): ...
- 关于PYTHON里SUPER使用时报的typeerror错误 - dongua的日志 - 网易博客
关于PYTHON里SUPER使用时报的typeerror错误 - dongua的日志 - 网易博客 关于PYTHON里SUPER使用时报的typeerror错误 2009-08-25 17:16:08 ...
- Python 关于super 的 用法和原理(挖坑)
一.前言 Python 面向对象中有继承这个概念,初学时感觉很牛逼,里面也有个super类,经常见到,最近做一些题才算是理解了.特地记录分享给后来研究的小伙伴,毕竟现在小学生都开始学了(滑稽脸) 二. ...
最新文章
- ios 设置属性的center_ios center.x设置
- 搭建consul 集群
- 【实验】广域网点到点协议PPP PAP CHAP的双向验证、单项认证
- mysql主主复制某张表_MySQL主主复制实战
- 存储过程或视图的字符串查询
- Oracle定时器调用存储过程
- AODV中实施watchdog
- Android——基于监听器的事件处理(转)
- linux egrep和grep区别,linux中grep和fgrep有什么区别
- BAT变TAT?2019年互联网各梯队排名重组
- Python3 高级编程
- 一些值得学习的Unity教程
- HBase常用Shell命令详解
- Nodejs Blob流方式下载
- linux创建虚拟目录意义,配置虚拟主机和虚拟目录
- GOPROXY:解决 go get golang.org/x 包失败
- Representation Learning 表示学习(简单笔记)
- AJP:有和没有内化性精神障碍的受虐女孩情绪回路延迟成熟的差异性
- idea如何关闭代码提示,设置快捷键提示代码
- AHOI2019N省联考凉凉记
热门文章
- Asp.net MVC中Html.Partial, RenderPartial, Action,RenderAction 区别和用法【转发】
- MySQL模拟:线上误update的恢复
- 乱码的根本原因是字节和字符的问题(转)
- python处理时间加减
- 不是VIP用户也不怕 不需任何补丁屏蔽迅雷广告!
- 在matlab中如何使用SVM工具箱
- 【Python学习系列二十】scikit-learn库模型持久化
- idea mybatis generator插件_Mybatis使用自定义插件去掉POJO的Getter和Setter方法
- 工厂设计模式——简单工厂模式——未完待续
- Jenkins 技术篇-jenkins的下载、安装与配置