我们最常见的,可以说几乎唯一能见到的使用super的形式是:

class SubClass(BaseClass):def method(self):super(SubClass, self).method()#do some thing here...

其中,最常见的method()是__init__()

以前做过Java,刚刚接触Python的继承,的确感觉有点奇怪,有时候还能搞混。。。当然这还是因为Java是单继承,只能用接口实现类似多继承的方式,而Python就直接支持多继承。

当我第一次见到这个super()的时候,我想说,这是啥啊?为什么Python的super看起来这么奇怪呢?

super直接指向父类的实例不就得了么?为什么非得搞两个参数?

而且第一个参数还是自己的类名,而不是父类的类名!

既然是自己的类名你还费劲写一遍干嘛,干脆省略不得了?

第二个参数为啥是self?既然是self你省略不得了?

还有,super()返回的是个啥玩意啊,为什么可以.method() ? 难道他返回了一个BaseClass的instance么?

今天就来解答这一连串的问题。

1)super直接指向父类的实例不就得了么?

首先是不能指向,因为子类实例里面根本就没有一个父类实例,这跟java是不同的。详细看这里。

其次是即便像我们想象的,子类实例里有一个叫super的指针,指向父类的实例(这个父类实例在子类实例生成的时候自动生成了,是子类实例的一个‘成员’)。

但是由于多继承的存在,还是会有问题。这也是跟java不同,java不支持多继承,java用接口的方式实现多继承。

举个例子:

当只存在单继承的时候,一切很美好,就像java一样:

你只需要在重写方法的时候,用super去调用父类的方法,然后再做自己的事就可以了。

但是在多继承的情况下,一切都不美好了:

当艺人展示自己能力的时候,他说,父亲啊,你先展示自己的能力,然后我来!

但是父亲是谁? 他有两个父亲! 总不能写两遍 super.展示自己 吧?

那么我们自然想到,给super搞一个参数不得了,指出super的是哪个父类。

比如 super(歌手).展示自己(),super(演员).展示自己(),好像一切又可以美好了:

先不说这种写法多么的丑陋,重复了那么多无意义的、类似的行,单说这种方法根本就行不通。

我们看看如果某个艺人的实例调用了.展示能力() ,将会输出什么:

我是人类,我能走路!
我是歌手,我能唱歌!
我是人类,我能走路!
我是演员,我能演戏!
我是艺人,我能代言广告!

有必要告诉大家两遍你是个人类么?这要是一个又身兼了主持人的艺人,岂不是得大声宣布三次自己是个人类??

这显然是不好的。

而且,这只是其一,假设多说了几遍自己是人类你也能忍,那么还有一种情况,更糟。

你比如说,艺人类没有重写 展现自己() 这个方法,当你用艺人的实例去调用 展现自己()的时候,将会发生啥?

不重写的方法自动调用父类的,但是有两个父类呀!调用哪个的呢?任意调用一个(比如按从左到右的顺序)?

那么体现不出他另一个父类的特点呀!比如调用歌手类的,那只能体现出这个艺人既是个歌手,又是个人类,根本体现不出他是个演员!

两个都调用?那万一其中一个父类没有这个方法呢?而且先调用哪个后调用哪个?按照左右顺序么?

总之这样很乱,编译器表示压力很大。

所以,python的super()用了两个参数。

先写在这里:

super(SubClass, self).method() 的意思是,根据self去找SubClass的‘父亲’,然后调用这个‘父亲’的method()

最最重点的地方来了:对于一个类来说,它的‘父类’到底是谁,取决于站在谁的角度去看。

‘父亲’之所以加了引号,是因为‘父亲’并不一定是上下级的继承关系,很可能只是兄弟。比如上图中歌手的‘父亲’是‘演员’,但实际上他们是兄弟关系。

所以以后用‘下一个类’来代替这个带引号的‘父亲’。

总之,站在不同的实例的角度,看到的‘下一个类’是不同的。

这就是super()第二个参数————self 的意义。

如果是一个歌手实例调用的,那么self=歌手实例,super()将站在一个歌手的角度,去找歌手类的‘下一个类’,则会找到人类;

如果是一个艺人实例调用的,那么self=艺人实例,super()将站在一个艺人的角度,去找歌手类的‘下一个类’,则会找到演员。

代码如下:

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class People(object):def show_my_power(self):print(u"I am a people, I can walk !")class Singer(People):def show_my_power(self):super(Singer, self).show_my_power()print(u"I am a singer, I can sing !")class Actor(People):def show_my_power(self):super(Actor, self).show_my_power()print(u"I am an actor, I can act !")class Artist(Singer, Actor):passif __name__ == "__main__":a = Artist()a.show_my_power()

运行结果:

I am a people, I can walk !
I am an actor, I can act !
I am a singer, I can sing !

这里需要注意:当一个类从多个类继承的时候,按照从左到右的顺序。

也就是说,站在艺人的角度,首先看到艺人类的‘下一个类’是歌手类,然后歌手类的‘下一个类’是演员类。

这是因为歌手写在了左边:Artist(Singer, Actor)

看一下上面代码的执行过程吧:

由于 super() 绝大多数时候,都在咱们开篇说的这种情况下使用,即在类的定义语句块内部写:super(本类名,self)

所以 python3 做了个简化,如果你在类定义的语句块内写一个不带参数的super(),则相当于写了 super(本类名,self)

因为 super() 不光可以用在类的定义内部,所以,这种方便仅在类定义体内部有效。

Python的Super方法相关推荐

  1. python之父去面试-Python面试题之Python的Super方法

    当我第一次见到这个super()的时候,我想说,这是啥啊?为什么Python的super看起来这么奇怪呢? super直接指向父类的实例不就得了么?为什么非得搞两个参数? 而且第一个参数还是自己的类名 ...

  2. python 中super方法的调用

    参考https://www.runoob.com/python/python-func-super.html 加以解释 class FooParent(object):def __init__(sel ...

  3. python的super方法_Python中“super”是做什么的?

    有什么不同?SomeBaseClass.__init__(self) 意味着调用SomeBaseClass的__init__.而 super(Child, self).__init__() 意味着__ ...

  4. Python基础教程:super()方法详解

    一.单独调用父类的方法 需求:编写一个类,然后再写一个子类进行继承,使用子类去调用父类的方法1. 使用方法1打印: 胖子老板,来包槟榔. 那么先写一个胖子老板的父类,执行一下: class FatFa ...

  5. python类的继承super方法_Python类的继承super相关原理解析

    看了网上许多关于super.mro.C3的介绍感觉没有一份很容易初学者理解的文档,直接看C3算法的话,比较难理解,也没必要,如果掌握一套规律的话,会轻松许多.我将网上这些博主的文章进行一个梳理总结,最 ...

  6. pythonsuper继承规则,深入理解Python中的super()方法

    前言 python的类分别有新式类和经典类,都支持多继承.在类的继承中,如果你想要重写父类的方法而不是覆盖的父类方法,这个时候我们可以使用super()方法来实现 python语言与C++有相似的类继 ...

  7. python 多继承与super使用详解_Python super()方法、多继承以及MRO顺序

    仅供学习,转载请注明出处 单独调用父类的方法 需求:编写一个类,然后再写一个子类进行继承,使用子类去调用父类的方法1. 使用方法1打印: 胖子老板,来包槟榔. 那么先写一个胖子老板的父类,执行一下: ...

  8. python super()方法的作用_详解python的super()的作用和原理

    Python中对象方法的定义很怪异,第一个参数一般都命名为self(相当于其它语言的this),用于传递对象本身,而在调用的时候则不必显式传递,系统会自动传递.uz0免费资源网 今天我们介绍的主角是s ...

  9. python面向编程:类继承、继承案例、单继承下属性查找、super方法

    一.类的继承 二.基于继承解决类与类的代码冗余问题 三.在单继承背景下属性的查找 四.super的方法 一.类的继承 1.什么是继承? 在程序中继承是一种新建子类的方法的方式,新创建的类成为子类\派生 ...

最新文章

  1. ios xmlrpc
  2. jvm性能调优实战 - 43OOM内存溢出发生的原因及可能发生OOM的内存区域
  3. 【操作系统】Semaphore处理吸烟者问题
  4. b超可以看出什么_B超可以查出什么
  5. mysql投资_[Leetcode]585. 2016年的投资(MySQL)
  6. base64编码_动画演示 Base 64 编码
  7. 使用Html5+C#+微信 开发移动端游戏详细教程 :(二)准备工作开发环境
  8. 少儿编程scratch系统介绍(附网站源码)
  9. docker下修改mysql配置文件
  10. 基于Android的记事本APP设计与实现
  11. 目录_网易微专业C++系统工程师
  12. Flume下读取kafka数据后再打把数据输出到kafka,利用拦截器解决topic覆盖问题
  13. Dubbo comsumer 远程调用流程分析
  14. python爬取微信公众号文章
  15. Latex书籍模板分享
  16. 下载IEEE期刊Latex模板步骤
  17. 解决Pycharm 多线程时出现错误Process finished with exit code -1073741819 (0xC0000005)
  18. esp分区中的EFI启动项文件有什么用
  19. 用友NC65产品的对账节点联查业务帐
  20. IDEA断点无效问题解决办法

热门文章

  1. linux消息队列操作
  2. 哇,union的优先级很高嘛
  3. CString 用法
  4. mysql varchar char text
  5. 查看linux字符集命令,关于Linux字符集的查看及修改
  6. 【增强】FI行项目报表增强任意字段
  7. Oracle 查看表空间的大小及使用情况sql语句
  8. SAP新财务系列之科目层次
  9. ABAP 几个文件相关的函数
  10. SAP收货时自动创建采购订单