详解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模拟enum枚举类型的方法小结
Apr 30 Python
21行Python代码实现拼写检查器
Jan 25 Python
python进阶_浅谈面向对象进阶
Aug 17 Python
python使用Tesseract库识别验证
Mar 21 Python
Python3.5.3下配置opencv3.2.0的操作方法
Apr 02 Python
Python 实现字符串中指定位置插入一个字符
May 02 Python
pyttsx3实现中文文字转语音的方法
Dec 24 Python
python实现XML解析的方法解析
Nov 16 Python
基于Django OneToOneField和ForeignKey的区别详解
Mar 30 Python
Pycharm打开已有项目配置python环境的方法
Jul 03 Python
Django封装交互接口代码
Jul 12 Python
python实现数据结构中双向循环链表操作的示例
Oct 09 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(1)
2006/10/09 PHP
php _autoload自动加载类与机制分析
2012/02/10 PHP
深入HTTP响应状态码速查表的详解
2013/06/07 PHP
CodeIgniter框架提示Disallowed Key Characters的解决办法
2014/04/21 PHP
javascript生成/解析dom的CDATA类型的字段的代码
2007/04/22 Javascript
List the UTC Time on a Computer
2007/06/11 Javascript
js不完美解决click和dblclick事件冲突问题
2012/07/16 Javascript
js Dialog 实践分享
2012/10/22 Javascript
javascript静态页面传值的三种方法分享
2013/11/12 Javascript
JavaScript异步编程Promise模式的6个特性
2014/04/03 Javascript
js和jquery中循环的退出和继续下一个循环
2014/09/03 Javascript
js实现的Easy Tabs选项卡用法实例
2015/09/06 Javascript
JS操作COOKIE实现备忘记录的方法
2016/04/01 Javascript
基于JavaScript实现 网页切出 网站title变化代码
2016/04/03 Javascript
JS基于clipBoard.js插件实现剪切、复制、粘贴
2016/05/03 Javascript
js当前页面登录注册框,固定div,底层阴影的实例代码
2016/10/04 Javascript
原生js验证简洁注册登录页面
2016/12/17 Javascript
Angular使用Md5加密的解决方法
2017/09/16 Javascript
vue路由懒加载的实现方法
2018/03/12 Javascript
浅谈ElementUI中switch回调函数change的参数问题
2018/08/24 Javascript
angular6 填坑之sdk的方法
2018/12/27 Javascript
vue3.0+vue-router+element-plus初实践
2020/12/02 Vue.js
Python断言assert的用法代码解析
2018/02/03 Python
python 多线程重启方法
2019/02/18 Python
python selenium 查找隐藏元素 自动播放视频功能
2019/07/24 Python
在python shell中运行python文件的实现
2019/12/21 Python
Tensorflow实现在训练好的模型上进行测试
2020/01/20 Python
Python猴子补丁Monkey Patch用法实例解析
2020/03/23 Python
tensorflow pb to tflite 精度下降详解
2020/05/25 Python
使用Python画了一棵圣诞树的实例代码
2020/11/27 Python
HTML5 Canvas入门学习教程
2016/03/17 HTML / CSS
阿里健康官方海外旗舰店:阿里健康国际自营
2017/11/24 全球购物
Skyscanner加拿大:全球旅行搜索平台
2018/11/19 全球购物
short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?
2014/09/26 面试题
夫妻分居协议书范本(有子女版)
2014/11/01 职场文书
基于Python实现对比Exce的工具
2022/04/07 Python