详解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实现批量重命名文件的代码
May 25 Python
Python实现的检测web服务器健康状况的小程序
Sep 17 Python
关于Python元祖,列表,字典,集合的比较
Jan 06 Python
详解Django的CSRF认证实现
Oct 09 Python
set在python里的含义和用法
Jun 24 Python
python将字符串list写入excel和txt的实例
Jul 20 Python
基于django传递数据到后端的例子
Aug 16 Python
通过Turtle库在Python中绘制一个鼠年福鼠
Feb 03 Python
python图形界面开发之wxPython树控件使用方法详解
Feb 24 Python
Python正则表达式如何匹配中文
May 27 Python
python中wheel的用法整理
Jun 15 Python
Python测试框架:pytest学习笔记
Oct 20 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
C#静态方法与非静态方法实例分析
2014/09/22 PHP
php实现字符串反转输出的方法
2015/03/14 PHP
深入浅析PHP7.0新特征(五大新特征)
2015/10/29 PHP
laravel请求参数校验方法
2019/10/10 PHP
Laravel相关的一些故障解决
2020/08/19 PHP
一个刚完成的layout(拖动流畅,不受iframe影响)
2007/08/17 Javascript
javascript写的日历类(基于pj)
2010/12/28 Javascript
javascript:history.go()和History.back()的区别及应用
2012/11/25 Javascript
jquery验证手机号码、邮箱格式是否正确示例代码
2013/07/28 Javascript
jquery按回车提交数据的代码示例
2013/11/05 Javascript
改变隐藏的input中value值的方法
2014/03/19 Javascript
javascript实现全角与半角字符的转换
2015/01/07 Javascript
Jquery全屏相册插件zoomvisualizer具有调节放大与缩小功能
2015/11/02 Javascript
利用JQuery写一个简单的异步分页插件
2016/03/07 Javascript
每日十条JavaScript经验技巧(一)
2016/06/23 Javascript
jQuery实现智能判断固定导航条或侧边栏的方法
2016/09/04 Javascript
JS实现类似百叶窗下拉菜单效果
2016/12/30 Javascript
原生JavaScript实现Tooltip浮动提示框特效
2017/03/07 Javascript
微信小程序自定义组件之可清除的input组件
2018/07/17 Javascript
[10:49]2014国际邀请赛 叨叨刀塔第二期为真正的电竞喝彩
2014/07/21 DOTA
Python RuntimeError: thread.__init__() not called解决方法
2015/04/28 Python
详解django实现自定义manage命令的扩展
2019/08/13 Python
Python中PyQt5/PySide2的按钮控件使用实例
2019/08/17 Python
Python 函数用法简单示例【定义、参数、返回值、函数嵌套】
2019/09/20 Python
wxPython实现画图板
2020/08/27 Python
python ImageDraw类实现几何图形的绘制与文字的绘制
2020/02/26 Python
解决reload(sys)后print失效的问题
2020/04/25 Python
Python 可视化神器Plotly详解
2020/12/26 Python
世界上最大的糖果店:Dylan’s Candy Bar
2017/11/07 全球购物
简历中个人求职的自我评价模板
2013/11/29 职场文书
模具专业毕业生自荐书范文
2014/02/19 职场文书
拆迁委托协议书
2014/09/15 职场文书
2014年向国旗敬礼活动总结
2014/09/27 职场文书
大学生实训报告总结
2014/11/05 职场文书
青年志愿者服务活动总结
2015/05/06 职场文书
七夕情人节问候语
2015/11/11 职场文书