首页 > 编程语言 >想了解Python中的super 函数么

想了解Python中的super 函数么

时间:2022-09-05 17:37:47浏览次数:86  
标签:run 函数 Python self print super class def

摘要:经常有朋友问,学 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 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):
 super().run()
d = D()
d.run()

此时输出的结果是 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. 如果到最后都没有找到,程序报错。

 

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

标签:run,函数,Python,self,print,super,class,def
From: https://www.cnblogs.com/huaweiyun/p/16658923.html

相关文章

  • Python 如何将字符串转为字典
    实习工作中需要将每行读取的字符串例如'{"A":"sad","B":"123"}'这种形式中的123取出来,查找到了这篇文章,对我很有帮助。转载一下防止遗失。将一个 python 的字符串转为......
  • Python22-逻辑运算符
    逻辑运算符逻辑运算符经常和关系运算符一起使用,通过逻辑运算符来连接多个关系运算符参与的数据:主要就是bool类型的数据比较之后的结果是:bool类型#与and一假俱......
  • 第十四章 函数的基本使用
    一、概述基于前一部分的学习,我们已经能开发一些功能简单的小程序了,但随着程序功能的增多,代码量随之增大,此时仍不加区分地把所有功能的实现代码放到一起,将会使得程序的组织......
  • Python引入matplotlib
    Matplotlib是一个 Python 的2D绘图库,它以各种硬拷贝格式和跨平台的交互式环境生成出版质量级别的图形。通过Matplotlib,开发者可以仅需要几行代码,便可以生成绘图,直方图......
  • js实现切换页面清除定时器的函数
    背景:我在切换页面的时候,发现切换回原来的页面,定时器会叠加而不会清除原来的定时器解决方法:1.定义全局变量,通过js遍历清除(不会用,但性能好)varpageTimer={};/......
  • 物理不可克隆函数-PUF
     时间:2022/09/05 一.简介PUF技术是一组微型延迟电路,其通过提取芯片制造过程中的差异,生成无数个独特的、不可预测的“密钥”。输入也称为激励(Challenge),输出也称为......
  • Python21-关系运算符
    关系运算符也称为比较运算符参与的数据:主要就是数值a=100b=300c=200d=100print(a>b)#Falseprint(c<b)#Trueprint(a==d)#Trueprint(......
  • 用递归函数计算s=1+2+3+4+.....+99+100
    #include<stdio.h>staticintci=0;intsum(inti){ci++;intm=0;if(i<100){m=i+sum(i+1);printf("%d",m);retur......
  • 10.2 函数调用的参数传递_位置实参_关键字实参
     defcalc(a,b):#a,b是形参,在函数定义处c=a+breturncresult=calc(10,20)#按位置传递参数#10,20为实参,在函数调用处print(re......
  • E10——常用函数——SqlValidate
    Context.SqlValidate(“SQL语句”,参数列表,参数值列表)举例:工单单头“生产批号”字段在维护的时候校验是否存在工单状态是未生产,已发料,生产中的工单引用过该生产批号,如果......