本文分享自华为云社区《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 () 函数的实战场景。
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()
复制代码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()
复制代码__mro__ 属性的说明。
MRO 是 method resolution order,即方法解析顺序,其本质是继承父类方法时的顺序表。
在 Python 中可以使用内置属性 __mro__ 查看方法的搜索顺序,例如下述代码,重点查看输出部分内容。
在 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'>)
复制代码A. 找到方法,停止检索;
B. 没有找到,继续检索下一类;
C. 如果到最后都没有找到,程序报错。
B. 没有找到,继续检索下一类;
C. 如果到最后都没有找到,程序报错。