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算法的话,这样就不难理解了。

preference:

https://segmentfault.com/a/1190000007426467  Python: 你不知道的 super

时间: 2024-10-10 09:24:19

super 使用以及原理的相关文章

类继承super原理

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 的 M

self和super之间的区别

关于 self 和 super 之间的区别, 首先要了解  1, self  是什么 :super 是什么.2,[ super init] 做什么.3,为什么要 self =  [super init]; 1,self  是什么 ,super 是什么 > 在动态方法中,self代表着"对象" > 在静态方法中,self代表着"类" > 万变不离其宗,记住一句话就行了:self代表着当前方法的调用者 self 和 super 是oc 提供的 两个保留

self与super的区别

要点: self调用自己方法,super调用父类方法 self是类,super是预编译指令 [self class]和[super class]输出是一样的 self和super底层实现原理: 当使用 self 调用方法时,会从当前类的方法列表中开始找,如果没有,就从父类中再找:而当使用 super 时,则从父类的方法列表中开始找,然后调用父类的这个方法. 当使用 self 调用时,会使用 objc_msgSend 函数: id objc_msgSend(id theReceiver, SEL

详解super用法

一.super() 的入门使用 - 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能, 这时,我们就需要调用父类的方法了,可通过使用 super 来实现,比如: class Animal(object): def __init__(self, name): self.name = name def greet(self): print("Hello, I am %s." %self.name) class Dog(Animal): de

python中super的使用

转自:http://python.jobbole.com/86787/ super() 的入门使用 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能,这时,我们就需要调用父类的方法了,可通过使用 super 来实现,比如: class Animal(object): def __init__(self, name): self.name = name def greet(self): print 'Hello, I am %s.' % self.

转载 你不知道的super

http://funhacks.net/2016/11/09/super/ 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能,这时,我们就需要调用父类的方法了,可通过使用 super 来实现,比如: 1 class Animal(object): 2 def __init__(self, name): 3 self.name = name 4 def greet(self): 5 print 'Hello, I am %s.' % self.na

前端路由原理及vue-router介绍

前端路由原理本质就是监听 URL 的变化,然后匹配路由规则,显示相应的页面,并且无须刷新.目前单页面使用的路由就只有两种实现方式 hash history www.test.com/##/ 就是 Hash URL,当 ## 后面的哈希值发生变化时,不会向服务器请求数据,可以通过 hashchange 事件来监听到 URL 的变化,从而进行跳转页面. vue-router hash实现源码(完整源码访问https://github.com/vuejs/vue-router/blob/dev/src

IOS开发——UI进阶篇(十一)应用沙盒,归档,解档,偏好设置,plist存储,NSData,自定义对象归档解档

1.iOS应用数据存储的常用方式XML属性列表(plist)归档Preference(偏好设置)NSKeyedArchiver归档(NSCoding)SQLite3 Core Data 2.应用沙盒每个iOS应用都有自己的应用沙盒(应用沙盒就是文件系统目录),与其他文件系统隔离.应用必须待在自己的沙盒里,其他应用不能访问该沙盒应用沙盒的文件系统目录,如下图所示(假设应用的名称叫Layer)模拟器应用沙盒的根路径在: (apple是用户名, 8.0是模拟器版本)/Users/apple/Libra

block注意事项

1.block的声明和注意事项 #import "ZYViewController.h" @interface ZYViewController () @end /*用typedef可以声明一种类型的block*/ //block前加上typedef, 那么就不是一个block指针(变量),而是一种block类型 //给int (^) (int a, int b) 这种block类型 声明了一个别名,叫做Block5 typedef int (^Block5) (int a, int