详解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网络编程学习笔记(二):socket建立网络客户端
Jun 09 Python
python之wxPython菜单使用详解
Sep 28 Python
在Python中使用next()方法操作文件的教程
May 24 Python
教大家玩转Python字符串处理的七种技巧
Mar 31 Python
Python用户推荐系统曼哈顿算法实现完整代码
Dec 01 Python
python实现用户管理系统
Jan 10 Python
python字符串循环左移
Mar 08 Python
python的一些加密方法及python 加密模块
Jul 11 Python
使用Python调取任意数字资产钱包余额功能
Aug 15 Python
Django框架获取form表单数据方式总结
Apr 22 Python
tensorflow 2.0模式下训练的模型转成 tf1.x 版本的pb模型实例
Jun 22 Python
python字符串的多行输出的实例详解
Jun 08 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
实用函数2
2007/11/08 PHP
发款php蜘蛛统计插件只要有mysql就可用
2010/10/12 PHP
PHP中strtotime函数使用方法分享
2012/01/10 PHP
PHP中如何调用webservice的实例参考
2013/04/25 PHP
Laravel中Trait的用法实例详解
2016/03/16 PHP
Yii2实现上下联动下拉框功能的方法
2016/08/10 PHP
php基于环形链表解决约瑟夫环问题示例
2017/11/07 PHP
一个js实现的所谓的滑动门
2007/05/23 Javascript
关于Jquery操作Cookie取值错误的解决方法
2013/08/26 Javascript
jquery按回车提交数据的代码示例
2013/11/05 Javascript
关于js中for in的缺陷浅析
2013/12/02 Javascript
简单谈谈JS数组中的indexOf方法
2016/10/13 Javascript
一个Js文件函数中调用另一个Js文件函数的方法演示
2017/08/14 Javascript
详解React Native 屏幕适配(炒鸡简单的方法)
2018/06/11 Javascript
js拖动滑块和点击水波纹效果实例代码
2018/10/16 Javascript
详解Vue实战指南之依赖注入(provide/inject)
2018/11/13 Javascript
JS实现audio音频剪裁剪切复制播放与上传(步骤详解)
2020/07/28 Javascript
[01:21:36]CHAOS vs Alliacne 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/16 DOTA
[01:05:59]Mineski vs Secret 2019国际邀请赛淘汰赛 败者组 BO3 第二场 8.22
2019/09/05 DOTA
Python的Django框架中设置日期和字段可选的方法
2015/07/17 Python
python实现机器人行走效果
2018/01/29 Python
PyQt5实现五子棋游戏(人机对弈)
2020/03/24 Python
Python发送邮件的实例代码讲解
2019/10/16 Python
HTML5基于flash实现播放RTMP协议视频的示例代码
2020/12/04 HTML / CSS
Paradox London官方网站:英国新娘鞋婚礼鞋品牌
2019/08/29 全球购物
天游软件面试
2013/11/23 面试题
params有什么用
2016/03/01 面试题
Linux内核的同步机制是什么?主要有哪几种内核锁
2016/07/11 面试题
婚前协议书怎么写
2014/04/15 职场文书
工作分析计划书
2014/04/30 职场文书
科技节口号
2014/06/19 职场文书
食品质量与安全专业毕业生求职信
2014/08/11 职场文书
“四风”问题整改措施和努力方向
2014/09/20 职场文书
师德师风自我剖析材料
2014/09/27 职场文书
幼儿园小班开学寄语
2015/05/27 职场文书
Springboot/Springcloud项目集成redis进行存取的过程解析
2021/12/04 Redis