Python中的super函数,你熟吗?

摘要:经常有朋友问,学 Python 面向对象时,翻阅别人代码,会发现一个 super() 函数,那这个函数的作用到底是什么?

本文分享自华为云社区《Python中的super函数怎么学,怎么解?》,作者: 梦想橡皮擦。

实战场景

经常有朋友问,学 Python 面向对象时,翻阅别人代码,会发现一个 super() 函数,那这个函数的作用到底是什么?

super() 函数的用途如下,在子类中调用父类的方法,多用于类的继承关系。

其语法格式如下所示:

super(type[, object-or-type])

参数说明如下:

  • type:类,可选参数
  • object-or-type:对象或类,一般为 self,也是可选参数。

返回值是代理对象。

可以直接查询官方帮助手册:

help(super)

输出信息如下所示:

Help on class super in module builtins:
class super(object)
 |  super() -> same as super(__class__, <first argument>)
 |  super(type) -> unbound super object
 |  super(type, obj) -> bound super object; requires isinstance(obj, type)
 |  super(type, type2) -> bound super object; requires issubclass(type2, type)
 |  Typical use to call a cooperative superclass method:
 |  class C(B):
 |      def meth(self, arg):
 |          super().meth(arg)
 |  This works for class methods too:
 |  class C(B):
 |      @classmethod
 |      def cmeth(cls, arg):
 |          super().cmeth(arg)

对输出结果进行分析之后,可以得到如下结论:

  • super 类是一个继承自 object 的类,super() 函数就是对该类的实例化;
  • 调用 super() 实例化之后,返回一个 super 对象;
  • super() 参数有四种搭配,具体看上述输出;

实战编码

单继承使用

直接看一下单继承相关代码,其中使用类名去调用父类方法。

class A:
 def funA(self):
 print("执行 A ,输出橡皮擦")
class B(A):
 def funB(self):
 # self 表示 B 类的实例
 A.funA(self)
 print("执行 B ,输出铅笔")
b = B()
b.funB()

上述代码在 B 类中增加了 funB 函数,并且去调用 A 类中的 funA 函数,此时输出的内容如下所示:

执行 A ,输出橡皮擦
执行 B ,输出铅笔

如果将上述代码修改为 super() 函数调用父类方法,可以使用下述代码:

class A:
 def funA(self):
 print("执行 A ,输出橡皮擦")
class B(A):
 def funB(self):
 # 注意 super() 函数的用法
 super().funA()
 print("执行 B ,输出铅笔")
b = B()
b.funB()

上述代码与之前的运行结果一致,在单继承的层级结构中,super 可以直接引用父类,即在子类中不需要使用父类名调用父类方法,而使用 代理对象(super 对象) 去调用,这样的好处就是当父类名改变或继承关系发生改变时,我们不需要对调用进行反复修改。

接下来看一下多继承情况下,super() 函数的实战场景。

class A:
 def funA(self):
 print("执行 A ,输出橡皮擦")
class B(A):
 def funB(self):
 # 注意 super() 函数的用法
 super().funA()
 print("执行 B ,输出铅笔")
b = B()
b.funB()

此时输出的结果是 AAA,可以看到 super 匹配到的数据是 A 类中的 run 函数,也就是最左侧类中的方法,下面修改一下各类中 run 函数的名称,使其存在差异。

class A:
 def run1(self):
 print('AAA')
class B:
 def run2(self):
 print('BBB')
class C:
 def run3(self):
 print('CCC')
class D(A, B, C):
 def run(self):
 # 调用 B 中 run2
 super().run2()
d = D()
d.run()

当一个类继承多个类时,如果第一个父类中没有提供该方法,当前类实例就会通过 __mro__ 属性进行向上搜索,如果到 object 类都没有检索到该方法,就会引发 AttributeError 异常。

基于上述逻辑,我们可以扩展一下,使用 super() 函数中的参数。

class A:
 def run(self):
 print('AAA')
class B:
 def run(self):
 print('BBB')
class C:
 def run(self):
 print('CCC')
class D(A, B, C):
 def run(self):
 # 调用 C 中 run
 super(B, self).run()
d = D()
d.run()

此时输出的结果是 CCC,该结果输出表示了使用 super 函数之后,可以使用 super(类,self) 指定以哪个类为起点检索父类中的方法,上述代码设置的 B,就表示从 B 开始检索,后续找到了 C 类,其中包含 run() 方法,所以输出 CCC。

__mro__ 属性的说明。

MRO 是 method resolution order,即方法解析顺序,其本质是继承父类方法时的顺序表。
在 Python 中可以使用内置属性 __mro__ 查看方法的搜索顺序,例如下述代码,重点查看输出部分内容。

class A:
 def run(self):
 print('AAA')
class B:
 def run(self):
 print('BBB')
class C:
 def run(self):
 print('CCC')
class D(A, B, C):
 def run(self):
 # 调用 C 中 run
 super(B, self).run()
print(D.__mro__)

输出的结果如下所示:

(<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class 'object'>)

你可以修改一下继承顺序,然后得到不同的输出结果。

(<class '__main__.D'>, <class '__main__.A'>, <class '__main__.C'>, <class '__main__.B'>, <class 'object'>)

在搜索方法的时候,是按照 __mro__ 的输出结果从左到右进行顺序查找的,逻辑如下:

A. 找到方法,停止检索;
B. 没有找到,继续检索下一类;
C. 如果到最后都没有找到,程序报错。

 

点击关注,第一时间了解华为云新鲜技术~

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python中的super函数,你熟吗? - Python技术站

(0)
上一篇 2023年4月2日 下午4:58
下一篇 2023年4月2日

相关文章

  • 云原生容器高可用运维能力应用

    摘要:华为云容器SRE在海量集群和容器运维实践中,从智能运维能力、确定性场景恢复等多方面总结出一套确定性运维实践,以应对云原生业务快速增长。 本文分享自华为云社区《云原生容器高可用运维能力应用》,作者:陈勇/刘志超/袁文峰。 云原生场景下,对架构高可用、应用高可用、基础云平台高可用提出了更高的要求,企业以及云平台都在不断致力于稳定性建设。但面对海量复杂的客户…

    云计算 2023年4月17日
    00
  • 读书笔记丨理解和学习事务,让你更好地融入云原生时代

    摘要:分布式事务与云原生技术有很强的关联,可以帮助云原生应用程序实现高效的分布式事务处理。 本文分享自华为云社区《理解和学习事务,让你更好地融入云原生时代》,作者: breakDawn。 随着云原生的概念越来越火,服务的架构应该如何发展和演进,成为很多程序员关心的话题。大名鼎鼎的《深入理解java虚拟机》一书作者于21年推出了新作《凤凰架构》,从这本书中可以…

    云计算 2023年5月8日
    00
  • 掌握动态规划,从“什么问题适合用”及“解题思路”入手

    摘要:一般是用动态规划来解决最优问题。 本文分享自华为云社区《深入浅出动态规划算法(中)》,作者:嵌入式视觉 。 一,“一个模型三个特征”理论讲解 一个模型指的是适合用动态规划算法解决的问题的模型,这个模型也被定义为“多阶段决策最优解模型”。具体解释如下: 一般是用动态规划来解决最优问题。而解决问题的过程,需要经历多个决策阶段。每个决策阶段都对应着一组状态。…

    人工智能概论 2023年4月24日
    00
  • Python图像处理丨详解图像去雾处理方法

    摘要:本文主要讲解ACE去雾算法、暗通道先验去雾算法以及雾化生成算法。 本文分享自华为云社区《[Python图像处理] 三十.图像预处理之图像去雾详解(ACE算法和暗通道先验去雾算法)丨【拜托了,物联网!】》,作者:eastmount 。 一.图像去雾 随着社会的发展,环境污染逐渐加剧,越来越多的城市频繁出现雾霾,这不仅给人们的身体健康带来危害,还给那些依赖…

    2023年4月2日
    00
  • 华为云新一代iPaaS全域融合集成平台全新升级

    摘要:基于华为十多年的数字化转型实践,华为云通过组装式交付、数智驱动、DevOps、服务化架构、安全可信、韧性6大关键技术助力客户实现应用现代化和高质量增长,华为云新一代iPaaS全域融合集成平台ROMA Connect也应运而生。 本文分享自华为云社区《华为云新一代iPaaS全域融合集成平台全新升级!》,作者:华为云头条。 数字化浪潮席卷,未来每一家企业都…

    云计算 2023年4月18日
    00
  • 青年开发者说:了不起的“桩源”守护者,开启智能充电新模式

    摘要:听来自深圳大学的高校开发者们,分享基于华为云技术创新、收获成功的故事。代码改变世界,2023年华为开发者大赛不容错过! 本文分享自华为云社区《青年开发者说:了不起的“桩源”守护者,开启智能充电新模式》,作者:华为云社区精选 。 “桩源守护者”,一个听起来有点热血、又充满了英雄主义色彩的词,这是由四个来自深圳大学的青年开发者组成的团队,他们基于华为云开发…

    人工智能概论 2023年5月5日
    00
  • 昇腾实战丨DVPP媒体数据处理视频解码问题案例

    摘要:本期就分享几个关于DVPP视频解码问题的典型案例,并给出原因分析及解决方法 本文分享自华为云社区《DVPP媒体数据处理视频解码问题案例》,作者:昇腾CANN 。 DVPP(Digital Vision Pre-Processing)是昇腾AI处理器内置的图像处理单元,通过AscendCL媒体数据处理接口提供强大的媒体处理硬加速能力,主要功能包括图像编解…

    人工智能概论 2023年5月8日
    00
  • Python从0到1丨图像增强及运算:形态学开运算、闭运算和梯度运算

    摘要:本文主要介绍图像形态学处理,详细讲解了图像开运算、闭运算和梯度运算。数学形态学是一种应用于图像处理和模式识别领域的新方法,其基本思想是用具有一定形态的结构元素去量度和提取图像中对应形状以达到对图像分析和识别目的。 本文分享自华为云社区《[Python从零到壹] 四十八.图像增强及运算篇之形态学开运算、闭运算和梯度运算》,作者: eastmount 。 …

    2023年3月31日
    00
合作推广
合作推广
分享本页
返回顶部