详解python的super()的作用和原理
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):方法解析顺序 进行的。后续会详细介绍一下这个MRO机制。
详解python的super()的作用和原理相关推荐
- python super()方法的作用_详解python的super()的作用和原理
Python中对象方法的定义很怪异,第一个参数一般都命名为self(相当于其它语言的this),用于传递对象本身,而在调用的时候则不必显式传递,系统会自动传递.uz0免费资源网 今天我们介绍的主角是s ...
- 详解python中GPU版本的opencv常用方法介绍
更多编程教程请到:菜鸟教程 https://www.piaodoo.com/ 友情链接:好看站 http://www.nrso.net/ 高州阳光论坛https://www.hnthzk.com/ 引 ...
- 详解 Python 源码之对象机制
在Python中,对象就是在堆上申请的结构体,对象不能是被静态初始化的,并且也不能是在栈空间上生存的.唯一的例外就是类型对象(type object),Python中所有的类型对象都是被静态初始化的. ...
- python如何安装matplotlib_详解python安装matplotlib库三种失败情况
(可能只有最后一句命令有用,可能全篇都没用) (小白方法,可能只适用于本人情况) 安装matplotlib时,出现的三种失败情况 1.read timed out 一开始我在pycharm终端使用pi ...
- python中list[1啥意思_详解Python中list[::-1]的几种用法
本文主要介绍了Python中list[::-1]的几种用法,分享给大家,具体如下: s = "abcde" list的[]中有三个参数,用冒号分割 list[param1:para ...
- pythonnamedtuple定义类型_详解Python中namedtuple的使用
namedtuple是Python中存储数据类型,比较常见的数据类型还有有list和tuple数据类型.相比于list,tuple中的元素不可修改,在映射中可以当键使用. namedtuple: na ...
- python join_详解Python中的join()函数的用法
函数:string.join() Python中有join()和os.path.join()两个函数,具体作用如下: join(): 连接字符串数组.将字符串.元组.列表中的元素以指定的字符(分隔符) ...
- python getattr_详解 Python 的二元算术运算,为什么说减法只是语法糖?
原题 | Unravelling binary arithmetic operations in Python 作者 | Brett Cannon 译者 | 豌豆花下猫("Python猫&q ...
- python装饰器由浅入深_详解Python装饰器由浅入深
装饰器的功能在很多语言中都有,名字也不尽相同,其实它体现的是一种设计模式,强调的是开放封闭原则,更多的用于后期功能升级而不是编写新的代码.装饰器不光能装饰函数,也能装饰其他的对象,比如类,但通常,我们 ...
最新文章
- Netty源码解析8-ChannelHandler实例之CodecHandler
- B+树比B树更适合索引
- golang 二维切片
- python函数的目的与意义_Python函数的概念和使用
- php+控制器+数据库,Laravel5.1数据库连接、创建数据库、创建model及创建控制器的方法_PHP...
- CVPR 2022 中科院、腾讯提出LAS-AT,利用“可学习攻击策略”进行“对抗训练”
- java方法调用制作万年历,基于JAVA的万年历api调用代码实例
- matlab图像取反_matlab图像处理
- Bzoj1972: [Sdoi2010]猪国杀 题解(大模拟+耐心+细心)
- 震撼人心的爱·《山月不知心底事》·一
- PNG、IconFont、SVG图标使用
- 展示正在活动时间内的活动,过期活动不显示
- python--pyecharts地图、地图标记可视化实现《四》--地图可视化[视觉盛宴]
- 7-5 梅森数 (10 分)
- ThinkPad E40 XP 安装SATA/AHCI驱动
- 疯狂天才霍兹:17岁黑掉苹果,22岁搞垮索尼,还是特斯拉、谷歌最可怕的对手!
- 假设将15个MSA连入超级高铁网络,如何用最少的轨道连接所有MSA?
- 已解BL锁的华为手机救砖以及root
- Nodejs koa2读取服务器图片返回给前端直接展示
- 2020CCPC-绵阳站-Joy of Handcraft (线段树因子拆分)
热门文章
- jQuery筛选器常用总结
- C# WinForm程序退出的方法比较
- ZOJ3865:Superbot(BFS) The 15th Zhejiang University Programming Contest
- C++预处理和头文件保护符
- C++程序员笔试复习概要(一)
- EntLib.com Forum – 开源ASP.NET论坛 v4.0(提供源码下载)
- linux ospf 命令,Linux运维知识之linux下使用quagga配置ospf协议
- html5纪念日期代码,HTML5适合的情人节礼物有纪念日期功能
- php 获取返回值,求助 如何获取php socket 返回值
- java http服务端例子_简单的用 Java Socket 编写的 HTTP 服务器应用