详解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使用any判断一个对象是否为空的方法
Nov 19 Python
Python使用scrapy采集时伪装成HTTP/1.1的方法
Apr 08 Python
Python操作MongoDB数据库PyMongo库使用方法
Apr 27 Python
python常用知识梳理(必看篇)
Mar 23 Python
Python嵌套式数据结构实例浅析
Mar 05 Python
解决Python正则表达式匹配反斜杠''\''问题
Jul 17 Python
用python的turtle模块实现给女票画个小心心
Nov 23 Python
python3实现在二叉树中找出和为某一值的所有路径(推荐)
Dec 26 Python
Python中断多重循环的几种方式详解
Feb 10 Python
Python使用urllib模块对URL网址中的中文编码与解码实例详解
Feb 18 Python
iPython pylab模式启动方式
Apr 24 Python
使用python将微信image下.dat文件解密为.png的方法
Nov 30 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生成验证码时“图像因其本身有错无法显示”的解决方法
2013/08/07 PHP
php实现检查文章是否被百度收录
2015/01/27 PHP
php事件驱动化设计详解
2016/11/10 PHP
PHP实现使用DOM将XML数据存入数组的方法示例
2017/09/27 PHP
js 事件处理函数间的Event物件是否全等
2011/04/08 Javascript
原生js拖拽(第一课 未兼容)拖拽思路
2013/03/29 Javascript
js正则表达exec与match的区别说明
2014/01/29 Javascript
javascript背景时钟实现方法
2015/06/18 Javascript
JavaScript基础知识之方法汇总结
2016/01/24 Javascript
jQuery弹出div层过2秒自动消失
2016/11/29 Javascript
详解Js中的模块化是如何实现的
2017/10/18 Javascript
nodejs基于WS模块实现WebSocket聊天功能的方法
2018/01/12 NodeJs
微信小程序实现YDUI的ScrollNav组件
2018/02/02 Javascript
利用vue.js实现被选中状态的改变方法
2018/02/08 Javascript
JS使用栈判断给定字符串是否是回文算法示例
2019/03/04 Javascript
vue中根据时间戳判断对应的时间(今天 昨天 前天)
2019/12/20 Javascript
Python读取键盘输入的2种方法
2015/06/16 Python
Python 操作文件的基本方法总结
2017/08/10 Python
Python 文件数据读写的具体实现
2020/01/24 Python
详解Python中namedtuple的使用
2020/04/27 Python
Python3 requests模块如何模仿浏览器及代理
2020/06/15 Python
利用Python实现斐波那契数列的方法实例
2020/07/26 Python
css3 边框、背景、文本效果的实现代码
2018/03/21 HTML / CSS
澳大利亚汽车零部件、音响及配件超市:Automotive Superstore
2018/06/19 全球购物
德国专业木制品经销商:Holz-Direkt24
2019/12/26 全球购物
英国在线定做百叶窗网站:Make My Blinds
2020/08/17 全球购物
美国室内盆栽植物购买网站:Plants.com
2020/04/24 全球购物
自我评价怎么写好呢?
2013/12/05 职场文书
乡文化站暑期培训方案
2014/08/28 职场文书
夫妻分居协议书范文
2014/11/26 职场文书
法定代表人证明书
2014/11/28 职场文书
开学典礼校长致辞
2015/07/29 职场文书
2016年寒假社会实践活动总结
2015/10/10 职场文书
PhpSpreadsheet中文文档 | Spreadsheet操作教程实例
2021/04/01 PHP
利用python调用摄像头的实例分析
2021/06/07 Python
vue特效之翻牌动画
2022/04/20 Vue.js