详解python的super()的作用和原理


Posted in Python onOctober 29, 2020

Python中对象方法的定义很怪异,第一个参数一般都命名为self(相当于其它语言的this),用于传递对象本身,而在调用的时候则不必显式传递,系统会自动传递。

今天我们介绍的主角是super(), 在类的继承里面super()非常常用, 它解决了子类调用父类方法的一些问题, 父类多次被调用时只执行一次, 优化了执行逻辑,下面我们就来详细看一下。

举一个例子:

class Foo:

  def bar(self, message):

    print(message)
>>> Foo().bar("Hello, Python.")

Hello, Python.

当存在继承关系的时候,有时候需要在子类中调用父类的方法,此时最简单的方法是把对象调用转换成类调用,需要注意的是这时self参数需要显式传递,例如:

class FooParent:

  def bar(self, message):

    print(message)

class FooChild(FooParent):

  def bar(self, message):

    FooParent.bar(self, message)
>>> FooChild().bar("Hello, Python.")

Hello, Python.

这样做有一些缺点,比如说如果修改了父类名称,那么在子类中会涉及多处修改,另外,Python是允许多继承的语言,如上所示的方法在多继承时就需要重复写多次,显得累赘。为了解决这些问题,Python引入了super()机制,例子代码如下:

class FooParent:

  def bar(self, message):

    print(message)

class FooChild(FooParent):

  def bar(self, message):

    super(FooChild, self).bar(message)
>>> FooChild().bar("Hello, Python.")

Hello, Python.

表面上看 super(FooChild, self).bar(message)方法和FooParent.bar(self, message)方法的结果是一致的,实际上这两种方法的内部处理机制大大不同,当涉及多继承情况时,就会表现出明显的差异来,直接给例子:

代码一

class A:

  def __init__(self):

    print("Enter A")

    print("Leave A")

class B(A):

  def __init__(self):

    print("Enter B")

    A.__init__(self)

    print("Leave B")

class C(A):

  def __init__(self):

    print("Enter C")

    A.__init__(self)

    print("Leave C")

class D(A):

  def __init__(self):

    print("Enter D")

    A.__init__(self)

    print("Leave D")

class E(B, C, D):

  def __init__(self):

    print("Enter E")

    B.__init__(self)

    C.__init__(self)

    D.__init__(self)

    print("Leave E")

E()

输出结果

Enter E

Enter B

Enter A

Leave A

Leave B

Enter C

Enter A

Leave A

Leave C

Enter D

Enter A

Leave A

Leave D

Leave E

执行顺序很好理解,唯一需要注意的是公共父类A被执行了多次。

代码二

class A:

  def __init__(self):

    print("Enter A")

    print("Leave A")

class B(A):

  def __init__(self):

    print("Enter B")

    super(B, self).__init__()

    print("Leave B")

class C(A):

  def __init__(self):

    print("Enter C")

    super(C, self).__init__()

    print("Leave C")

class D(A):

  def __init__(self):

    print("Enter D")

    super(D, self).__init__()

    print("Leave D")

class E(B, C, D):

  def __init__(self):

    print("Enter E")

    super(E, self).__init__()

    print("Leave E")

E()

输出结果

Enter E

Enter B

Enter C

Enter D

Enter A

Leave A

Leave D

Leave C

Leave B

Leave E

在super机制里可以保证公共父类仅被执行一次,至于执行的顺序,是按照MRO(Method Resolution Order):方法解析顺序 进行的。

以上就是详解python的super()的作用和原理的详细内容,更多关于python super()的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python在windows和linux下获得本机本地ip地址方法小结
Mar 20 Python
Python在Console下显示文本进度条的方法
Feb 14 Python
Python第三方库xlrd/xlwt的安装与读写Excel表格
Jan 21 Python
详解Python 模拟实现生产者消费者模式的实例
Aug 10 Python
Python爬取附近餐馆信息代码示例
Dec 09 Python
python提取包含关键字的整行数据方法
Dec 11 Python
python如何给字典的键对应的值为字典项的字典赋值
Jul 05 Python
python 自定义装饰器实例详解
Jul 20 Python
python 标准差计算的实现(std)
Jul 29 Python
Python列表切片常用操作实例解析
Dec 16 Python
如何基于matlab相机标定导出xml文件
Nov 02 Python
Pandas数据结构之Series的使用
Mar 31 Python
Python生成pdf目录书签的实例方法
Oct 29 #Python
利用python清除移动硬盘中的临时文件
Oct 28 #Python
python实现一个简单RPC框架的示例
Oct 28 #Python
pycharm永久激活超详细教程
Oct 29 #Python
linux mint中搜狗输入法导致pycharm卡死的问题
Oct 28 #Python
浅谈Python __init__.py的作用
Oct 28 #Python
详解Selenium-webdriver绕开反爬虫机制的4种方法
Oct 28 #Python
You might like
根德Grundig S400/S500/S700电路分析
2021/03/02 无线电
php结合表单实现一些简单功能的例子
2011/06/04 PHP
php图片处理函数获取类型及扩展名实例
2014/11/19 PHP
PHP数组和explode函数示例总结
2015/05/08 PHP
php邮件发送的两种方式
2020/04/28 PHP
thinkphp框架实现删除和批量删除
2016/06/29 PHP
php查找字符串中第一个非0的位置截取
2017/02/27 PHP
php+ajax 文件上传代码实例
2019/03/18 PHP
PHP字符串中抽取子串操作实例分析
2019/06/22 PHP
JavaScript中令你抓狂的魔术变量
2006/11/30 Javascript
微信 java 实现js-sdk 图片上传下载完整流程
2016/10/21 Javascript
完美解决IE不支持Data.parse()的问题
2016/11/24 Javascript
Three.js基础学习教程
2017/11/16 Javascript
jquery 获取索引值在一定范围的列表方法
2018/01/25 jQuery
Angular ng-animate和ng-cookies用法详解
2018/04/18 Javascript
JavaScript callback回调函数用法实例分析
2018/05/08 Javascript
vue element项目引入icon图标的方法
2018/06/06 Javascript
基于Node.js的大文件分片上传示例
2019/06/19 Javascript
js实现带积分弹球小游戏
2020/07/21 Javascript
[01:01:25]DOTA2上海特级锦标赛B组资格赛#2 Fnatic VS Spirit第三局
2016/02/27 DOTA
[01:24:16]2018DOTA2亚洲邀请赛 4.6 全明星赛
2018/04/10 DOTA
Django1.7+python 2.78+pycharm配置mysql数据库教程
2014/11/18 Python
Python利用Beautiful Soup模块修改内容方法示例
2017/03/27 Python
django_orm查询性能优化方法
2018/08/20 Python
使用python3实现操作串口详解
2019/01/01 Python
jupyter lab的目录调整及设置默认浏览器为chrome的方法
2020/04/10 Python
python读取hdfs上的parquet文件方式
2020/06/06 Python
canvas压缩图片以及卡片制作的方法示例
2018/12/04 HTML / CSS
Canvas获取视频第一帧缩略图的实现
2020/11/11 HTML / CSS
澳大利亚冲浪和时尚服装网上购物:SurfStitch
2017/07/29 全球购物
Java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类
2012/02/06 面试题
2014年元旦感言
2014/03/06 职场文书
2014年重阳节老干部座谈会上的讲话稿
2014/09/25 职场文书
银行开户授权委托书格式
2014/10/10 职场文书
家长意见书
2015/06/04 职场文书
2016消防宣传标语口号
2015/12/26 职场文书