详解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实现的登陆Discuz!论坛通用代码分享
Jul 11 Python
python计算对角线有理函数插值的方法
May 07 Python
Python语言实现机器学习的K-近邻算法
Jun 11 Python
Centos Python2 升级到Python3的简单实现
Jun 21 Python
Python爬取京东的商品分类与链接
Aug 26 Python
python pygame实现2048游戏
Nov 20 Python
python实现AES加密和解密
Mar 27 Python
Python之pymysql的使用小结
Jul 01 Python
Django关于admin的使用技巧和知识点
Feb 10 Python
使用keras内置的模型进行图片预测实例
Jun 17 Python
python 获取谷歌浏览器保存的密码
Jan 06 Python
详解OpenCV获取高动态范围(HDR)成像
Apr 29 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
虫族 Zerg 魔法科技
2020/03/14 星际争霸
深入探讨<br />和 \r\n两者有什么区别??
2013/06/05 PHP
php简单的上传类分享
2016/05/15 PHP
YII2 实现多语言配置的方法分享
2017/01/11 PHP
javascript setTimeout()传递函数参数(包括传递对象参数)
2010/04/07 Javascript
js操作时间(年-月-日 时-分-秒 星期几)
2010/06/20 Javascript
javascript实现获取cookie过期时间的变通方法
2014/08/14 Javascript
JS实现自适应高度表单文本框的方法
2015/02/25 Javascript
JS设置cookie、读取cookie、删除cookie
2015/04/17 Javascript
jquery常用函数与方法汇总
2015/09/01 Javascript
jQuery实现简单的文件上传进度条效果
2020/03/26 Javascript
AngularJs学习第八篇 过滤器filter创建
2016/06/08 Javascript
jquery制做精致的倒计时特效
2016/06/13 Javascript
JS动态给对象添加属性和值的实现方法
2016/10/21 Javascript
详解nodejs 文本操作模块-fs模块(三)
2016/12/22 NodeJs
过期软件破解办法实例详解
2017/01/04 Javascript
vue.js开发环境安装教程
2017/03/17 Javascript
页面间固定参数,通过cookie传值的实现方法
2017/05/31 Javascript
基于AngularJS的简单使用详解
2017/09/10 Javascript
详解vue 数据传递的方法
2018/04/19 Javascript
python中global与nonlocal比较
2014/11/21 Python
Python中的错误和异常处理简单操作示例【try-except用法】
2017/07/25 Python
Python+OpenCV+pyQt5录制双目摄像头视频的实例
2019/06/28 Python
使用Python paramiko模块利用多线程实现ssh并发执行操作
2019/12/05 Python
python模式 工厂模式原理及实例详解
2020/02/11 Python
python 实现控制鼠标键盘
2020/11/27 Python
类的核心特性有哪些
2014/01/01 面试题
办公室驾驶员岗位职责
2013/11/15 职场文书
生物技术专业毕业生求职信范文
2013/12/14 职场文书
经销商会议欢迎词
2014/01/11 职场文书
安全生产责任书范本
2014/04/15 职场文书
2014年学生会干事工作总结
2014/11/07 职场文书
2014年校长工作总结
2014/12/11 职场文书
2015年个人实习工作总结
2014/12/12 职场文书
2015年圣诞节活动总结
2015/03/24 职场文书
2015年“世界无车日”活动方案
2015/05/06 职场文书