super 使用以及原理
用super也很久了,但是一直没有关注过他的原理。最近开始越来越多关注python更底层的实现和奇技淫巧。看到该方法越发使用得多所以也研究了一波
平时单继承可能是我们遇到最多的情况。无非就是类似情况。
class A(object):
def __init__(self, a, b):
print 'times gone away %s, %s' % (a, b) class B(A):
def __init__(self, a, b):
super(B, self).__init__(a, b) B(1, 2)
times gone away 1, 2
这个例子的类B继承了类A,然后在初始化方法里面调用了父类A的初始化方法并且传入了参数。
其实我想说就这个 例子来看。。这样也可以
class A(object):
def __init__(self, a, b):
print 'times gone away %s, %s' % (a, b) class B(A):
pass B(1, 2)
当然。调用父类初始化方法之后,我们依然在后面可以做一些 其他的操作,但是第二个例子就做不到了注意。
super看上去 也可以通过直接写父类A.__init__(self, a, b)来实现但是,当我们遇到多继承的时候情况就有所改变。super可以帮忙利用方法解析顺序(Method Resolution Order, MRO)列表来寻找按顺序顺着父类。在多继承的情况下,初始化循序并非我们所想的自底向上。
而是顺着mro列表从左到右。
B.mro() # or C.__mro__ or C().__class__.mro()
[<class '__main__.B'>, <class '__main__.A'>, <type 'object'>]
如上所示有三种方法查看该类的mro顺序。
从上面返回的数组我们可以看到,从顺序上看是B到A到 object的继承关系。
而super方法调用的本质是:
def super(cls, inst):
mro = inst.__class__.mro()
return mro[mro.index(cls) + 1]
我们将类名cls 和实例self传入,然后由mro找到自己的类位置并且+1 返回下个继承类调用位置。 而不是自底向上的寻找父类。 有这个公式可能就更容易明白了。
preference的这篇文章举了一个 完整的多继承例子,但是我觉得 只要你理解了 python中寻找父类的方法不是自底向上 而是依赖mro算法的话,这样就不难理解了。
Reference:
https://segmentfault.com/a/1190000007426467 Python: 你不知道的 super
super 使用以及原理的更多相关文章
- python: super原理
super() 的入门使用 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能,这时,我们就需要调用父类的方法了,可通过使用 super 来实现,比如: ...
- super的实例及实现原理
super实例 class A(): def go(self): print ("go A go!") def stop(self): print ("stop A st ...
- self和super之间的区别
关于 self 和 super 之间的区别, 首先要了解 1, self 是什么 :super 是什么.2,[ super init] 做什么.3,为什么要 self = [super init ...
- python中super()的一些用法
在看python高级编程这本书的时候,在讲到super的时候,产生了一些疑惑,super在python中的用法跟其他的语言有一些不一样的地方,在网上找了一些资料,发现基本上很少有文章能把我的疑惑讲明白 ...
- Python super使用
一 基础使用 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能,这时,我们就需要调用父类的方法了,可通过使用 super 来实现,比如: #!/usr ...
- Python: 你不知道的 super
https://segmentfault.com/a/1190000007426467 Python: 你不知道的 super 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我 ...
- Python super() 函数
super() 函数是用于调用父类(超类)的一个方法. super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果重定义某个方法,该方法会覆盖父类的同名方法,但有时 ...
- 转载 你不知道的super
http://funhacks.net/2016/11/09/super/ super仅被用于新式类 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能 ...
- python中super的使用
转自:http://python.jobbole.com/86787/ super() 的入门使用 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能, ...
随机推荐
- mybatis基础系列(三)——动态sql
本文是Mybatis基础系列的第三篇文章,点击下面链接可以查看前面的文章: mybatis基础系列(二)--基础语法.别名.输入映射.输出映射 mybatis基础系列(一)--mybatis入门 动态 ...
- vue-resource get/post请求如何携带cookie的问题
vue-resource get/post请求如何携带cookie的问题 当我们使用vue请求的时候,我们会发现请求头中没有携带cookie传给后台,我们可以在请求时添加如下代码:vue.http.o ...
- SVN 安装vs插件
1.下载visualsvn for visual studio 2012/2013/2015/2017 2.查看是否安装成功 一 下载并安装插件 1.VisualSVN :VisualSVN-5.1. ...
- omcat+java的web程序持续占cpu高问题调试【转】
1.top -c 2.查看具体线程 ps -m -p 30997 -o tid,%cpu,%mem > threads.log 3.printf %x 31865 其次将需要的线程ID转换为16 ...
- Eclipse-设置选中高亮显示
高亮显示选中的变量对于程序员编程很有帮助,正常情况下Eclipse选中变量时都会高亮显示,可能软件冲突导致高亮显示失效,通过如下方法可以进行恢复. 单击IDE顶部Window菜单下的Preferenc ...
- Python开发技巧
1 python关闭windows进程 python关闭windows进程的方法,涉及Python调用系统命令操作windows进程的技巧 import os command = 'taskkill ...
- C#集合Collections购物车Shopping Cart
这篇是对象与集合操练,物件的创建,集合的一些基本功能,如添加,编辑,删除等功能. 对象,即是网店的商品物件,Insus.NET只为其添加2个属性,物件的ID的Key和名称ItemName以及2个构造函 ...
- JavaFx之不通过全局静态变量进行窗体通信
百度了n多窗体通信,,,总是通过定义全局静态变量进行传值通信..我个人不喜欢一个controller里写满所有的布局(这样显得臃肿,但是组件传值方便).有没有另外的办法进行模块化并且可以传值呢.. 肯 ...
- Linux查看特定端口是否被占用并kill掉相关进程
今天在搭建Zookeeper集群的时候,需要频繁启动zookeeper,但是启动的时候,有时会提示下列错误信息: zookeeper需要的地址已经被占用了,其实是因为上一次的zookeeper没有关闭 ...
- Spring Cloud 入门教程(九): 路由网关zuul
在微服务架构中,需要几个关键的组件,服务注册与发现.服务消费.负载均衡.断路器.智能路由.配置管理等,由这几个组件可以组建一个简单的微服务架构.客户端的请求首先经过负载均衡(zuul.Ngnix),再 ...