转 -- 详解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中的split()函数的使用方法
这篇文章主要介绍了举例详解Python中的split()函数的使用方法,split()函数的使用是Python学习当中的基础知识,通常用于将字符串切片并转换为列表,需要的朋友可以参考下 函数:sp ...
- 详解Python中re.sub--转载
[背景] Python中的正则表达式方面的功能,很强大. 其中就包括re.sub,实现正则的替换. 功能很强大,所以导致用法稍微有点复杂. 所以当遇到稍微复杂的用法时候,就容易犯错. 所以此处,总结一 ...
- 详解Python函数参数定义及传参(必备参数、关键字参数、默认可省略参数、可变不定长参数、*args、**kwargs)
详解Python函数参数定义及传参(必备参数.关键字参数.默认可省略参数.可变不定长参数.*args.**kwargs) Python函数参数传参的种类 Python中函数参数定义及调用函数时传参 ...
- 详解python的装饰器decorator
装饰器本质上是一个python函数,它可以让其它函数在不需要任何代码改动的情况下增加额外的功能. 装饰器的返回值也是一个函数对象.它经常用于有切面需求的场景,比如:插入日志,性能测试,事务处理,缓存, ...
- 详解 Python 的二元算术运算,为什么说减法只是语法糖?
原题 | Unravelling binary arithmetic operations in Python 作者 | Brett Cannon 译者 | 豌豆花下猫("Python猫&q ...
- 【转】详解spring 每个jar的作用
spring.jar 是包含有完整发布模块的单个jar 包.但是不包括mock.jar, aspects.jar, spring-portlet.jar, and spring-hibernate2. ...
- 详解Python模块导入方法
python常被昵称为胶水语言,它能很轻松的把用其他语言制作的各种模块(尤其是C/C++)轻松联结在一起.python包含子目录中的模块方法比较简单,关键是能够在sys.path里面找到通向模块文件的 ...
- 详解python函数的参数
详解python函数的参数 一.参数的定义 1.函数的参数在哪里定义 在python中定义函数的时候,函数名后面的括号里就是用来定义参数的,如果有多个参数的话,那么参数之间直接用逗号, 隔开 案列: ...
- 详解Python 切片语法
Python的切片是特别常用的功能,主要用于对列表的元素取值.这篇文章主要介绍了详解Python 切片语法,需要的朋友可以参考下 Python的切片是特别常用的功能,主要用于对列表的元素取值.使用切片 ...
随机推荐
- dotnet core的下载地址 以及sdk和runtime的 version 简单说明
1. dotnet core 2.1 的下载地址 https://dotnet.microsoft.com/download/dotnet-core/2.1 2. dotnet core 2.2 的下 ...
- Java之map使用方法
package basic; import java.util.HashMap; import java.util.Map; //map使用方法 public class MapDemo { publ ...
- windows部分常用命令
dir 查看内容 md 新建目录 copy 复制 del 删文件 cls 清屏 tasklist 查看运行进程 taskkill /pid xxx 杀死进程xxx taskmgr 打开任务管理器 ms ...
- VMWare 安装 Linux
参考 : http://www.aboutyun.com/thread-6780-1-1.html 这的是很详细.赞一下 我这里就简化一下. 1 下载: VMWare : https://d ...
- POJ 1661 (Help Jimmy )
Help Jimmy Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 13669 Accepted: 4541 Descr ...
- MT【17】利用柯西不等式求三角的最大值
评:此题也可以设$1+cos\theta=t$,平方后变成$t$的单变量利用均值去做. 柯西平衡系数法其实就是待定系数法,利用等号取到的条件.
- centos Install Mrtg
安装支持软件包yum –y install gcc perl gd libpng zlib net-snmp mrtg配置snmpd编辑/etc/snmp/snmpd.conf文件备份snmpd.co ...
- LOJ #6435. 「PKUSC2018」星际穿越(倍增)
题面 LOJ#6435. 「PKUSC2018」星际穿越 题解 参考了 这位大佬的博客 这道题好恶心啊qwq~~ 首先一定要认真阅读题目 !! 注意 \(l_i<r_i<x_i\) 这个条 ...
- Twitter数据挖掘:如何使用Python分析大数据 (3)
让我们来拉取Twitter账号@NyTimes的最近20条微博. 我们可以创建变量来存放待拉取的微博数量(即count),以及待拉取的用户(即name).然后用这两个参数调用user_timeline ...
- 自学Linux Shell4.2-监测磁盘空间mount umount df du
点击返回 自学Linux命令行与Shell脚本之路 4.2-监测磁盘空间mount umount df du 1. 挂载存储媒体mount 移除存储媒体umount ls命令用于显示文件目录列表, ...