详解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通过apply使用元祖和列表调用函数实例
May 26 Python
详解python之多进程和进程池(Processing库)
Jun 09 Python
Python3实现爬取简书首页文章标题和文章链接的方法【测试可用】
Dec 11 Python
python网络应用开发知识点浅析
May 28 Python
python虚拟环境完美部署教程
Aug 06 Python
python3.7实现云之讯、聚合短信平台的短信发送功能
Sep 26 Python
详细分析Python collections工具库
Jul 16 Python
python try...finally...的实现方法
Nov 25 Python
详解python定时简单爬取网页新闻存入数据库并发送邮件
Nov 27 Python
python中time包实例详解
Feb 02 Python
Python3.9.1中使用match方法详解
Feb 08 Python
pyqt5打包成exe可执行文件的方法
May 14 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中防止伪造跨站请求的小招式
2011/09/02 PHP
php实现从上传文件创建缩略图的方法
2015/04/02 PHP
php实现背景图上添加圆形logo图标的方法
2016/11/17 PHP
jQuery的学习步骤
2011/02/23 Javascript
javascript管中窥豹 形参与实参浅析
2011/12/17 Javascript
让人蛋疼的JavaScript语法特性
2014/09/30 Javascript
jQuery 实现自动填充邮箱功能(带下拉提示)
2014/10/14 Javascript
AngularJS入门教程之过滤器用法示例
2016/11/02 Javascript
jQuery模拟窗口抖动效果
2017/03/15 Javascript
详解nodejs微信公众号开发——4.自动回复各种消息
2017/04/11 NodeJs
详解Angular 4.x NgTemplateOutlet
2017/05/24 Javascript
JavaScript实现自动跳转文本功能
2017/05/25 Javascript
javascript ES6 新增了let命令使用介绍
2017/07/07 Javascript
微信小程序分享海报生成的实现方法
2018/12/10 Javascript
使用layui+ajax实现简单的菜单权限管理及排序的方法
2019/09/10 Javascript
微信小程序点击顶部导航栏切换样式代码实例
2019/11/12 Javascript
vue+springboot+element+vue-resource实现文件上传教程
2020/10/21 Javascript
[00:27]DOTA2次级职业联赛 - Lilith战队宣传片
2014/12/01 DOTA
用PyQt进行Python图形界面的程序的开发的入门指引
2015/04/14 Python
Python3通过Luhn算法快速验证信用卡卡号的方法
2015/05/14 Python
Python 制作糗事百科爬虫实例
2016/09/22 Python
Python将一个CSV文件里的数据追加到另一个CSV文件的方法
2018/07/04 Python
pytorch训练imagenet分类的方法
2018/07/27 Python
Python爬虫基础之XPath语法与lxml库的用法详解
2018/09/13 Python
python 申请内存空间,用于创建多维数组的实例
2019/12/02 Python
python与pycharm有何区别
2020/07/01 Python
CSS3截取字符串实例代码【推荐】
2018/06/07 HTML / CSS
汉森批发:Hansen Wholesale
2018/05/24 全球购物
巴西美妆购物网站:Kutiz Beauté
2019/03/13 全球购物
Fossil加拿大官网:化石手表、手袋、首饰及配饰
2019/04/23 全球购物
外贸业务员求职自荐信分享
2013/09/21 职场文书
幼儿园亲子活动方案
2014/01/29 职场文书
社团招新策划书
2014/02/04 职场文书
2014年环保局工作总结
2014/12/11 职场文书
详细谈谈JavaScript中循环之间的差异
2021/08/23 Javascript
MySQL表类型 存储引擎 的选择
2021/11/11 MySQL