super的入门使用:

在类的继承中,如果定义某个方法,该方法会覆盖父类的同名方法,但有时候我们希望能同时实现父类的功能,这时,我们就需要调用父类的方法了,可以通过使用super来实现。比如:

class Animal(object):
def __init__(self, name):
self.name = name def greet(self):
print(self.name) class Dog(Animal):
def greet(self):
super(Dog, self).greet()
print('wang wang') obj = Dog('藏獒')
obj.greet()

示例

在上面代码中,Animal是父类,Dog是子类,我们在Dog类定义了greet方法,为了能同时实现父类的功能,我们又调用了父类的方法。
super的一个最常见用法可以说是在子类中调用父类的初始化方法了。

深入super:

以上的使用很简单,无非是获取了父类,并调用父类的方法。其实,在上面的情况下,super获得的类刚好是父类,但在其他情况就不一定了,super其实和父类没有实质性的关联。

首先看一个复杂点的例子,涉及多继承:

class Base(object):
def __init__(self):
print('enter base')
print('leave base') class A(Base):
def __init__(self):
print('enter A')
super(A, self).__init__()
print('leave A') class B(Base):
def __init__(self):
print('enter B')
super(B, self).__init__()
print('leave B') class C(A, B):
def __init__(self):
print('enter C')
super(C, self).__init__()
print('leave C') obj = C()

示例

其中,Base是父类,A、B继承Base,C继承A和B,执行结果如下:

enter C
enter A
enter B
enter base
leave base
leave B
leave A
leave C

如果你认为super代表调用父类的方法,那么你很可能疑惑为什么enterA的下一句不是enterBase而是enterB。原因是,super和父类没有实质性的关联,那么super是怎么运作的呢?
首先看一下MRO表吧:

(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.Base'>, <class 'object'>)

mro表是通过一个C3线性化算法来实现的,遵循三条原则:

  1、子类永远在父类前面

  2、如果有多个父类,会根据他们在列表中的顺序被检查

  3、如果对下一个类存在两个合法的选择,选择第一个父类

super原理:

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

其中,cls代表类,inst代表实例,上面的代码做了两件事:
  1、获取inst的mro列表

  2、查找cls在当前mro列表中的index,并返回它的下一个类,即mro[index+1]

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

现在,再回到上个示例:

首先看C的__init__方法:

super(C, self).__init__()
这里的self是当前实例,即使不创建对象,self也是一个固定的内存地址,这时会打印出enterA,并执行下面一行代码:
super(A, self).__init__()
注意:这里的self也是当前C的实例,mro表跟上面是一样的,搜索A在mro列表中的下一个类,发现是B,于是,跳到了B的__init__,这时会打印出enterB,而不是enter base

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

小结:

事实上,super和父类没有实质性的关联

super(cls,inst)获得的是cls在inst的mro列表中的下一个类。

super深究的更多相关文章

  1. 常用数据结构-线性表及Java 动态数组 深究

    [Java心得总结六]Java容器中——Collection在前面自己总结的一篇博文中对Collection的框架结构做了整理,这里深究一下Java中list的实现方式 1.动态数组 In compu ...

  2. WebComponent魔法堂:深究Custom Element 之 标准构建

    前言  通过<WebComponent魔法堂:深究Custom Element 之 面向痛点编程>,我们明白到其实Custom Element并不是什么新东西,我们甚至可以在IE5.5上定 ...

  3. python类中的super,原理如何?MRO是什么东东?

    下面这个URL解释得比较清楚. http://python.jobbole.com/86787/?utm_source=group.jobbole.com&utm_medium=related ...

  4. JavaSE复习日记 : 继承关系和super关键字以及继承关系中方法的覆写

    /* * 类的继承和super关键字 * * 软件开发的三大目的: * 可拓展性; * 可维护性; * 可重用性; * * 这里单说下可重用性这一项: * 为了代码复用,复用方式有: * 函数的调用复 ...

  5. JavaScript学习笔记(散)——继承、构造函数super

    构造函数中的super 今天看<JavaScript设计模式与开发实践>时,在书中看到一段代码出现super语句,第一次看到这个关键字,所以上网查了下它的作用,发现这个关键字是来自java ...

  6. Python super使用

    一 基础使用 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能,这时,我们就需要调用父类的方法了,可通过使用 super 来实现,比如: #!/usr ...

  7. Python: 你不知道的 super

    https://segmentfault.com/a/1190000007426467 Python: 你不知道的 super 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我 ...

  8. python: super原理

    super() 的入门使用 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能,这时,我们就需要调用父类的方法了,可通过使用 super 来实现,比如: ...

  9. Angular 个人深究(二)【发布与订阅】

    Angular 个人深究(二)[发布与订阅] 1. 再入正题之前,首先说明下[ 发布与订阅模式](也叫观察者模式) 1) 定义:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个 ...

随机推荐

  1. F#注解

    不要问我为啥要学F#——因为气质摆在那里 标注:以下内容均来自 anderslly F#系列 1.类型推演 let square x = x * x //接受一个某类型参数的quare函数返回一个这个 ...

  2. [日常] nginx与location规则

    =========================================================================2018年3月28日 记录: location = / ...

  3. java 全自动生成Excel之ExcelUtil篇(上一篇的升级版 [针对实体类对象的遍历赋值])

    看了上一篇随笔之后可以对本篇有更好的了解! 使用的poi的jar包依然是上一篇的poi-3.17.jar.... import pojo.UserPojo(上一篇里有,这里就不粘贴了!) 不废话了,直 ...

  4. Hibernate中查询优化策略

    Hibernate查询优化策略 ² 使用延迟加载等方式避免加载多余数据 ² 通过使用连接查询,配置二级缓存.查询缓存等方式减少select语句数目 ² 结合缓存机制,使用iterate()方法减少查询 ...

  5. JS全局变量VAR和THIS--在函数内部,加var是局部变量,不加是全局变量

    JS全局变量VAR和THIS 2011-05-23 21:43 很多人都觉得在JavaScript声明一个变量,加var和不加var没有什么区别,实际上是一个错误的观点,如果在函数外面,也就是说在wi ...

  6. opencv3.2.0图像对比度与亮度调整

    ##名称:图像对象度与对比度调整(由轨迹条分别控制对比度和亮度值) ##平台:QT5.7.1+opencv3.2.0 ##时间:2017年12月13日 /***********建立QT控制台程序*** ...

  7. Hadoop总结

    背景 Hadoop是一个由Apache基金会所开发的分布式系统基础架构.用户可以在不了解分布式底层细节的情况下,开发分布式程序.充分利用集群的威力进行高速运算和存储. Mapreduce1 vs YA ...

  8. Keras & Theano 输出中间层结果

    Keras & Theano get output of an intermediate layer 1.使用函数模型API,新建一个model,将输入和输出定义为原来的model的输入和想要 ...

  9. Mac下git的环境搭建和基本使用

    前言本文将介绍git的基本概念.环境搭建.日常使用,主要针对刚接触git,或接触不久,或好久没用忘记的同学们,当然是基于mac环境的,window系统也是大同小异!本文将从以下几个模块介绍,希望能帮助 ...

  10. Vue 框架-12-Vue 项目的详细开发流程

    Vue 框架-12-Vue 项目的详细开发流程 首先,如果你还不了解 Vue 脚手架怎么搭建? 默认的环境中有哪些文件? 文件大概是什么作用? 那么,您要先查看之前的文章才有助于你理解本篇文章: Vu ...