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. 三种数据库访问——Spring JDBC

    本篇随笔是上两篇的延续:三种数据库访问——原生JDBC:数据库连接池:Druid Spring的JDBC框架 Spring JDBC提供了一套JDBC抽象框架,用于简化JDBC开发. Spring主要 ...

  2. 上传多张图片imgupload

    <tr> <td class="listtitle-up">尿素箱</td> <td> <div class="co ...

  3. CSS 通过使用Important覆盖所有其他样式

    在许多情况下,您将使用CSS库.这些可能会意外覆盖您自己的CSS.所以当你绝对需要确定一个元素具有特定的CSS时,可以使用 !important. 让我们回到之前的 pink-text class 声 ...

  4. DotNet Core 2.0部署后外网IP访问

    将DotNet Core2.0项目部署在Ubuntu上并且运行后,可以用localhost:5000来访问. 但是如果这时候用外网来访问就不行了. 这时候就有两种解决方案,第一种是用Nginx做代理实 ...

  5. 插入sql返回主键id

    <insert id="insertSelective" parameterType="com.xxx.model.XDetail" useGenerat ...

  6. JVM之---Java源码编译机制

    Sun JDK中采用javac将Java源码编译为class文件,这个过程包含三个步骤:     1.分析和输入到符号表(Parse and Enter)    Parse过程所做的工作有词法和语法分 ...

  7. Mybatis源代码分析之parsing包

    parsing,从字面上理解就是编译解析的意思,那么这个包中的内容就应该和mybatis配置文件的编译解析有关系.本文首先会按照引用层次来分别介绍这个包中各个类的作用,而后再用实际的例子解释它们是如何 ...

  8. 获取本地内网和外网IP地址

    public class IPUtil { /// <summary> /// 获取本地内网IP /// </summary> /// <returns></ ...

  9. 《AlphaGo世纪对决》与周志华《机器学习》观后感

    这两天看了<AlphaGo世纪对决>纪录片与南大周志华老师的<机器学习>,想谈谈对人工智能的感想. 首先概述一下视频的内容吧,AlphaGo与李世石对战的过程大家都有基本的了解 ...

  10. HDU2102(KB2-I)

    A计划 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...