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()的作用和原理相关推荐

  1. python super()方法的作用_详解python的super()的作用和原理

    Python中对象方法的定义很怪异,第一个参数一般都命名为self(相当于其它语言的this),用于传递对象本身,而在调用的时候则不必显式传递,系统会自动传递.uz0免费资源网 今天我们介绍的主角是s ...

  2. 详解python中GPU版本的opencv常用方法介绍

    更多编程教程请到:菜鸟教程 https://www.piaodoo.com/ 友情链接:好看站 http://www.nrso.net/ 高州阳光论坛https://www.hnthzk.com/ 引 ...

  3. 详解 Python 源码之对象机制

    在Python中,对象就是在堆上申请的结构体,对象不能是被静态初始化的,并且也不能是在栈空间上生存的.唯一的例外就是类型对象(type object),Python中所有的类型对象都是被静态初始化的. ...

  4. python如何安装matplotlib_详解python安装matplotlib库三种失败情况

    (可能只有最后一句命令有用,可能全篇都没用) (小白方法,可能只适用于本人情况) 安装matplotlib时,出现的三种失败情况 1.read timed out 一开始我在pycharm终端使用pi ...

  5. python中list[1啥意思_详解Python中list[::-1]的几种用法

    本文主要介绍了Python中list[::-1]的几种用法,分享给大家,具体如下: s = "abcde" list的[]中有三个参数,用冒号分割 list[param1:para ...

  6. pythonnamedtuple定义类型_详解Python中namedtuple的使用

    namedtuple是Python中存储数据类型,比较常见的数据类型还有有list和tuple数据类型.相比于list,tuple中的元素不可修改,在映射中可以当键使用. namedtuple: na ...

  7. python join_详解Python中的join()函数的用法

    函数:string.join() Python中有join()和os.path.join()两个函数,具体作用如下: join(): 连接字符串数组.将字符串.元组.列表中的元素以指定的字符(分隔符) ...

  8. python getattr_详解 Python 的二元算术运算,为什么说减法只是语法糖?

    原题 | Unravelling binary arithmetic operations in Python 作者 | Brett Cannon 译者 | 豌豆花下猫("Python猫&q ...

  9. python装饰器由浅入深_详解Python装饰器由浅入深

    装饰器的功能在很多语言中都有,名字也不尽相同,其实它体现的是一种设计模式,强调的是开放封闭原则,更多的用于后期功能升级而不是编写新的代码.装饰器不光能装饰函数,也能装饰其他的对象,比如类,但通常,我们 ...

最新文章

  1. Netty源码解析8-ChannelHandler实例之CodecHandler
  2. B+树比B树更适合索引
  3. golang 二维切片
  4. python函数的目的与意义_Python函数的概念和使用
  5. php+控制器+数据库,Laravel5.1数据库连接、创建数据库、创建model及创建控制器的方法_PHP...
  6. CVPR 2022 中科院、腾讯提出LAS-AT,利用“可学习攻击策略”进行“对抗训练”
  7. java方法调用制作万年历,基于JAVA的万年历api调用代码实例
  8. matlab图像取反_matlab图像处理
  9. Bzoj1972: [Sdoi2010]猪国杀 题解(大模拟+耐心+细心)
  10. 震撼人心的爱·《山月不知心底事》·一
  11. PNG、IconFont、SVG图标使用
  12. 展示正在活动时间内的活动,过期活动不显示
  13. python--pyecharts地图、地图标记可视化实现《四》--地图可视化[视觉盛宴]
  14. 7-5 梅森数 (10 分)
  15. ThinkPad E40 XP 安装SATA/AHCI驱动
  16. 疯狂天才霍兹:17岁黑掉苹果,22岁搞垮索尼,还是特斯拉、谷歌最可怕的对手!
  17. 假设将15个MSA连入超级高铁网络,如何用最少的轨道连接所有MSA?
  18. 已解BL锁的华为手机救砖以及root
  19. Nodejs koa2读取服务器图片返回给前端直接展示
  20. 2020CCPC-绵阳站-Joy of Handcraft (线段树因子拆分)

热门文章

  1. jQuery筛选器常用总结
  2. C# WinForm程序退出的方法比较
  3. ZOJ3865:Superbot(BFS) The 15th Zhejiang University Programming Contest
  4. C++预处理和头文件保护符
  5. C++程序员笔试复习概要(一)
  6. EntLib.com Forum – 开源ASP.NET论坛 v4.0(提供源码下载)
  7. linux ospf 命令,Linux运维知识之linux下使用quagga配置ospf协议
  8. html5纪念日期代码,HTML5适合的情人节礼物有纪念日期功能
  9. php 获取返回值,求助 如何获取php socket 返回值
  10. java http服务端例子_简单的用 Java Socket 编写的 HTTP 服务器应用