super实例

class A():
def go(self):
print ("go A go!")
def stop(self):
print ("stop A stop!")
def pause(self):
raise Exception("Not Implemented")
class B(A):
def go(self):
super(B, self).go()
print ("go B go!")
class C(A):
def go(self):
super(C, self).go()
print ("go C go!")
def stop(self):
super(C, self).stop()
print ("stop C stop!")
class D(B,C):
def go(self):
super(D, self).go()
print ("go D go!")
def stop(self):
super(D, self).stop()
print ("stop D stop!")
def pause(self):
print ("wait D wait!")
class E(B,C):
pass
a = A()
b = B()
c = C()
d = D()
e = E()
# 说明下列代码的输出结果
a.go()
print('--------')
b.go()
print('--------')
c.go()
print('--------')
d.go()
print('--------')
e.go()
print('--------')
a.stop()
print('--------')
b.stop()
print('--------')
c.stop()
print('--------')
d.stop()
print('--------')
e.stop()
print(D.mro())
a.pause()
b.pause()
c.pause()
d.pause()
e.pause()

答案

a.go()# go A go!
b.go()# go A go!# go B go!
c.go()# go A go!# go C go!
d.go()# go A go!# go C go!# go B go!# go D go!
e.go()# go A go!# go C go!# go B go!
a.stop()# stop A stop!
b.stop()# stop A stop!
c.stop()# stop A stop!# stop C stop!
d.stop()# stop A stop!# stop C stop!# stop D stop!
e.stop()# stop A stop!
a.pause()# ... Exception: Not Implemented
b.pause()# ... Exception: Not Implemented
c.pause()# ... Exception: Not Implemented
d.pause()# wait D wait!
e.pause()# ...Exception: Not Implemented

  

super原理

super的工作原理如下:

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

cls代表类,inst代表实例,可以看出上面的代码做了两件事:

  • 获取inst的MRO列表。
  • 查找cls在MRO的index,并返回它的下一个类,即mro[index + 1]

当你使用super(cls, inst)时,python会在inst的MRO列表上搜索下cls的下一个类。

现在再回答前面的例子:

super(C, self).__init__()

这里的self是C的实例,self.class.mro()的结果是;

[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.Base'>, <class 'object'>]

可以看到C的下一个类是A,于是,跳到了A的init,这时会打印enter A,并且执行下面一行代码:

super(A, self).__init__()

注意这里的self也是当前C的实例,MRO列表和之前是一样的。搜索A在MRO中下的一个类,发现是B,于是又跳到了B的init,这时会打印enter B,而不是enter Base。

上面整个过程还是比较清晰的,关键在于理解super的工作方式,而不是想当然的理解为super调用父类的方法。

总结:

  • super和父类没有实质性的关联。
  • super(cls, inst)获得的是cls在inst的MRO列表中下一个类。

super的实例及实现原理的更多相关文章

  1. 跟vczh看实例学编译原理——三:Tinymoe与无歧义语法分析

    文章中引用的代码均来自https://github.com/vczh/tinymoe.   看了前面的三篇文章,大家应该基本对Tinymoe的代码有一个初步的感觉了.在正确分析"print ...

  2. 跟vczh看实例学编译原理——一:Tinymoe的设计哲学

    自从<序>胡扯了快一个月之后,终于迎来了正片.之所以系列文章叫<看实例学编译原理>,是因为整个系列会通过带大家一步一步实现Tinymoe的过程,来介绍编译原理的一些知识点. 但 ...

  3. 跟vczh看实例学编译原理——零:序言

    在<如何设计一门语言>里面,我讲了一些语言方面的东西,还有痛快的喷了一些XX粉什么的.不过单纯讲这个也是很无聊的,所以我开了这个<跟vczh看实例学编译原理>系列,意在科普一些 ...

  4. Java JUC之Atomic系列12大类实例讲解和原理分解

    Java JUC之Atomic系列12大类实例讲解和原理分解 2013-02-21      0个评论       作者:xieyuooo 收藏    我要投稿 在java6以后我们不但接触到了Loc ...

  5. [面向对象之继承应用(在子类派生重用父类功能(super),继承实现原理(继承顺序、菱形问题、继承原理、Mixins机制),组合]

    [面向对象之继承应用(在子类派生重用父类功能(super),继承实现原理(继承顺序.菱形问题.继承原理.Mixins机制),组合] 继承应用 类与类之间的继承指的是什么'是'什么的关系(比如人类,猪类 ...

  6. Ajax实例OR技术原理 转自 (http://blog.csdn.net/evankaka )

    摘要:AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术.AJAX 是一种用于创建快速动态网页的 ...

  7. python基础----多态与多态性、super函数用法、继承原理

    一.多态与多态性                                                                        ㈠多态: 多态指的是一类事物有多种形态, ...

  8. Java面向对象之关键字super 入门实例

    一.基础概念 (一)super关键字 super关键字的用法和this相似.this代表的是当前对象.super代表的是父类中内存空间. 子父类中是不会出现同名属性的情况. (二)继承中.成员变量问题 ...

  9. Java反射学习总结四(动态代理使用实例和内部原理解析)

    通过上一篇文章介绍的静态代理Java反射学习总结三(静态代理)中,大家可以发现在静态代理中每一个代理类只能为一个接口服务,这样一来必然会产生过多的代理,而且对于每个实例,如果需要添加不同代理就要去添加 ...

随机推荐

  1. [Luogu] 运输计划

    https://www.luogu.org/problemnew/show/2680 inline 神奇的东西 最好戒掉吧(read()除外) 这道题将求解性问题转化为判定性问题,当然就是二分答案了 ...

  2. qt5.10 开发安卓之硌手的小虫子们

    1.jdk 下载: 下载地址:http://www.oracle.com/technetwork/java/javase/overview/index.html windows 平台不要下载java ...

  3. java 封装返回结果实体类 返回结果以及错误信息

    public class ResponseMessage { private final static String STATUS_OK = "0"; private final ...

  4. meshing-圆锥网格划分

    原视频下载地址: https://pan.baidu.com/s/1boSjGXh 密码: 9zis

  5. AHOI2012树屋阶梯

    这玩意不是卡特兰的经典模型吗…… 我们设方案数为f(i),则f(0)=1,f(1)=1,f(2)=2,f(3)=5,(其实到这里你再手模一个就出来了)我们把左上角的矩形删掉,则会变成下方和右方两个更小 ...

  6. LUA 在C函数中保存状态:registry、reference

    1 背景 lua的值一般都是保存在栈里面,调用函数完毕值在栈会被清掉,从而被GC回收.但有时候C函数需要在函数体的作用域之外保存某些Lua数据,这些数据不能存放在栈里面,有没有全局变量之类的可以存放. ...

  7. spring boot + vue 前后分离实现登录功能(一)

    使用webpack 打包初始化项目 vue init webpack book-vue 进入工程目录 cd hello-vue 安装 vue-router npm install vue-router ...

  8. thymeleaf 与shiro 整合错误

    错误 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { // ...

  9. js的一些兼容性易错的的问题

    一.属性相关 我们通常把特征(attribute)和属性(property)统称为属性,但是他们确实是不同的概念,特征(attribute)会表现在HTML文本中,对特征的修改一定会表现在元素的out ...

  10. qt 设置程序控件样式

    1. 以资源文件的形式设置控件样式 QFiledata(QString(":/style.qss")); QStringqssFile; if(data.open(QFile::R ...