详解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中使用pyhook实现键盘监控的例子
Jul 18 Python
Python检测一个对象是否为字符串类的方法
May 21 Python
python 实现删除文件或文件夹实例详解
Dec 04 Python
Python 专题一 函数的基础知识
Mar 16 Python
对Python字符串中的换行符和制表符介绍
May 03 Python
python和opencv实现抠图
Jul 18 Python
Python提取支付宝和微信支付二维码的示例代码
Feb 15 Python
tensorflow mnist 数据加载实现并画图效果
Feb 05 Python
windows下python安装pip方法详解
Feb 10 Python
浅谈keras.callbacks设置模型保存策略
Jun 18 Python
python zip()函数的使用示例
Sep 23 Python
python3通过subprocess模块调用脚本并和脚本交互的操作
Dec 05 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
php 处理上百万条的数据库如何提高处理查询速度
2010/02/08 PHP
关于PHP中Object对象的笔记分享
2011/06/28 PHP
php字符串截取函数mb_substr用法实例分析
2019/06/25 PHP
PHP设计模式(三)建造者模式Builder实例详解【创建型】
2020/05/02 PHP
强悍无比的WEB开发好助手FireBug(Firefox Plugin)
2007/01/16 Javascript
jQeury淡入淡出需要注意的问题
2010/09/08 Javascript
各种常用的JS函数整理
2013/10/25 Javascript
AngularJS入门教程之Hello World!
2014/12/06 Javascript
jQuery组件easyui基本布局实现代码
2016/08/25 Javascript
JS作用域深度解析
2016/12/29 Javascript
Vue数据驱动模拟实现1
2017/01/11 Javascript
滚动条的监听与内容随着滚动条动态加载的实现
2017/02/08 Javascript
JavaScript实现简单的四则运算计算器完整实例
2017/04/28 Javascript
js es6系列教程 - 新的类语法实战选项卡(详解)
2017/09/02 Javascript
Angular7创建项目、组件、服务以及服务的使用
2019/02/19 Javascript
微信小程序保存图片到相册权限设置
2020/04/09 Javascript
从零学python系列之从文件读取和保存数据
2014/05/23 Python
python3获取两个日期之间所有日期,以及比较大小的实例
2018/04/08 Python
Python基于scipy实现信号滤波功能
2019/05/08 Python
Python自动化之数据驱动让你的脚本简洁10倍【推荐】
2019/06/04 Python
Python当中的array数组对象实例详解
2019/06/12 Python
python中调试或排错的五种方法示例
2019/09/12 Python
pytorch 获取tensor维度信息示例
2020/01/03 Python
Python接口测试环境搭建过程详解
2020/06/29 Python
HTML5 3D书本翻页动画的实现示例
2019/08/28 HTML / CSS
流行文化收藏品:Sideshow(DC漫画,星球大战,漫威)
2019/03/17 全球购物
办公室文秘岗位职责
2013/11/15 职场文书
中学生班主任评语
2014/01/30 职场文书
幼儿园小班评语大全
2014/04/17 职场文书
学校消防安全责任书
2014/07/23 职场文书
工作转正自我鉴定范文
2019/06/21 职场文书
jquery插件实现搜索历史
2021/04/24 jQuery
python迷宫问题深度优先遍历实例
2021/06/20 Python
分享五个Node.js开发的优秀实践 
2022/04/07 NodeJs
使用vue判断当前环境是安卓还是IOS
2022/04/12 Vue.js
SpringBoot项目多数据源及mybatis 驼峰失效的问题解决方法
2022/07/07 Java/Android