super 调用委托给父类或兄弟类
内置函数(类)super,Python 官方文档描述如下:
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)
|
返回一个代理对象,它会将方法调用委托给类 type 的父类或兄弟类。这对于访问已在类中被重载的继承方法很有用。
super()
和super(__class__, <first argument>)
一样。- 如果省略第二个参数,则返回的超类对象是未绑定的。
- 如果第二个参数为一个对象,则 isinstance(obj, type) 必须为真值。
- 如果第二个参数为一个类型,则 issubclass(type2, type) 必须为真值(这适用于类方法)。
super 有两个典型用例:
- 在具有单继承的类层级结构中,super 可用来引用父类而不必显式地指定它们的名称,从而令代码更易维护。
- 第二个用例是在动态执行环境中支持协作多重继承。此用例为 Python 所独有。这使得实现 “菱形图” 成为可能,在这时会有多个基类实现相同的方法。好的设计强制要求这种方法在每个情况下具有相同的调用签名(因为调用顺序是在运行时确定的,也因为该顺序要适应类层级结构的更改,还因为该顺序可能包含在运行时之前未知的兄弟类)。
类或方法的 __mro__
属性列出了 getattr() 和 super() 所共同使用的方法解析顺序(MRO)。该属性是动态的,可以在任何继承层级结构发生更新的时候被改变。
除了方法查找之外,super() 也可用于属性查找。一个可能的应用场合是在上级或同级类中调用描述器。
请注意 super() 是作为显式加点属性查找的绑定过程的一部分来实现的,例如 super().__getitem__(name)
。它做到这一点是通过实现自己的 __getattribute__()
方法,这样就能以可预测的顺序搜索类,并且支持协作多重继承。
还要注意的是,除了零个参数的形式以外,super() 并不限于在方法内部使用。两个参数的形式明确指定参数并进行相应的引用。零个参数的形式仅适用于类定义内部,因为编译器需要填入必要的细节以正确地检索到被定义的类,还需要让普通方法访问当前实例。
方法调用委托给父类:
type(super)
type
class A:
def add(self, x):
y = x + x
print(y)
class B(A):
def add(self, x):
super().add(x) # super() 等价于 super(B,self)
b = B()
b.add(5)
10
初始化委托给父类:
class A:
def __init__(self):
self.a = '父类A'
print ('A')
def print_msg(self,a):
print (f'{a}来自A')
class B(A):
def __init__(self):
# super(B, self) 可写为 super()
super(B, self).__init__()
print ('B')
def print_msg(self,b):
super().print_msg(b)
print (f'{b}来自B')
print (self.a)
b = B()
b.print_msg('HelloWorld')
A
B
HelloWorld来自A
HelloWorld来自B
父类A