详解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的web框架中的Model的教程
Apr 29 Python
Python实现模拟登录网易邮箱的方法示例
Jul 05 Python
numpy.ndarray 交换多维数组(矩阵)的行/列方法
Aug 02 Python
详解Python下Flask-ApScheduler快速指南
Nov 04 Python
解决Python2.7中IDLE启动没有反应的问题
Nov 30 Python
Python pycharm 同时加载多个项目的方法
Jan 17 Python
python学生管理系统
Jan 30 Python
python过滤中英文标点符号的实例代码
Jul 15 Python
使用Python制作表情包实现换脸功能
Jul 19 Python
处理Selenium3+python3定位鼠标悬停才显示的元素
Jul 31 Python
详解用python生成随机数的几种方法
Aug 04 Python
Django如何使用redis作为缓存
May 21 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
在DC的漫画和电影中,蝙蝠侠的宿敌,小丑的真名是什么?
2020/04/09 欧美动漫
thinkphp实现多语言功能(语言包)
2014/03/04 PHP
PHP中CURL的CURLOPT_POSTFIELDS参数使用细节
2014/03/17 PHP
thinkphp5.0自定义验证规则使用方法
2017/11/16 PHP
TP5(thinkPHP5)框架使用ajax实现与后台数据交互的方法小结
2020/02/10 PHP
js 居中漂浮广告
2010/03/21 Javascript
为jQuery增加join方法的实现代码
2010/11/28 Javascript
jQuery把表单元素变为json对象
2013/11/06 Javascript
JS去除字符串两端空格的简单实例
2013/12/27 Javascript
原生JavaScript生成GUID的实现示例
2014/09/05 Javascript
分享一个自己写的简单的javascript分页组件
2015/02/15 Javascript
JS如何判断是否为ie浏览器的方法(包括IE10、IE11在内)
2015/12/13 Javascript
js实现人民币大写金额形式转换
2016/04/27 Javascript
在 Typescript 中使用可被复用的 Vue Mixin功能
2018/04/17 Javascript
Vue 让元素抖动/摆动起来的实现代码
2018/05/31 Javascript
JS实现图片拖拽交换效果
2018/11/30 Javascript
javscript 数组扁平化的实现
2020/02/03 Javascript
JavaScript 替换所有匹配内容及正则替换方法
2020/02/12 Javascript
在Uni中使用Vue的EventBus总线机制操作
2020/07/31 Javascript
Python中文件遍历的两种方法
2014/06/16 Python
python实现自动发送邮件发送多人、群发、多附件的示例
2018/01/23 Python
利用python-docx模块写批量生日邀请函
2019/08/26 Python
Python Tensor FLow简单使用方法实例详解
2020/01/14 Python
Django返回HTML文件的实现方法
2020/09/17 Python
详解HTML5中CSS外观属性
2020/09/10 HTML / CSS
上海中网科技笔试题
2012/02/19 面试题
华为python面试题
2016/05/03 面试题
大学生入党自我鉴定
2013/10/31 职场文书
经理秘书找工作求职信
2013/12/19 职场文书
大学生开西餐厅创业计划书
2014/02/01 职场文书
小学生校园广播稿
2014/09/28 职场文书
三年级作文之趣事作文
2019/11/04 职场文书
Python绘制分类图的方法
2021/04/20 Python
React-vscode使用jsx语法的问题及解决方法
2021/06/21 Javascript
深入浅出讲解Java8函数式编程
2022/01/18 Java/Android
Python 统计序列中元素的出现频度
2022/04/26 Python