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. mybatis 小结

    1.  根据后台list 在SQL中使用到In的时候 <if test="sbidList != null and sbidList.size() > 0"> A ...

  2. Angular的表单组件

    创建表单元素 在上一节中,我们学习了如何创建一个组件login,现在将login改造一下, 在template中添加html表单元素,#usernameRef表示input元素id,如果想传递inpu ...

  3. spring定时任务(@Scheduled注解)

    (一)在xml里加入task的命名空间 xmlns:task="http://www.springframework.org/schema/task" http://www.spr ...

  4. Wirshark 显示过滤器

    二层显示过滤: eth.addr==<MAC Address>:只显示具有指定mac地址 eth.src==<MAC Address>:只显示具有指定源MAC地址的数据帧 et ...

  5. python学习之老男孩python全栈第九期_数据库day004知识点总结 —— MySQL数据库day4

    复习: 1. MySQL:文件管理的软件 2. 三部分: - 服务端 - SQL语句 - 客户端 3. 客户端: - MySQL - navicat 4. 授权操作: - 用户操作 - 授权操作 5. ...

  6. python学习之老男孩python全栈第九期_数据库day002 -- 作业 (数据库为day001创建的数据库)

    1.自行创建测试数据 对score表进行优化: 添加数据: 2.查询“生物”课程比“物理”课程成绩高的所有学生的学号: 为了方便做题,额外增加几条数据 查询: 3.查询平均成绩大于60分的同学的学号和 ...

  7. PHP通用分页类page.php[仿google分页]

    <?php /** ** 通用php分页类.(仿Google样式) ** 只需提供记录总数与每页显示数两个参数.(已附详细使用说明..) ** 无需指定URL,链接由程序生成.方便用于检索结果分 ...

  8. elasticsearch 多列 聚合(sql group by)

    文档数据格式 {"zone_id":"1","user_id":"100008","try_deliver_t ...

  9. 构建微服务:快速搭建Spring Boot项目

    Spring Boot简介: Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员 ...

  10. 【Python】Java程序员学习Python(十一)— IO

    一.前言 io的内容其实还是有很多的,现在我也只是了解初步用法,当然详细内容还是应该参照官方api的: 官方api:https://docs.python.org/3/library/os.html. ...