super([type[, object-or-type]])
返回一个代理对象将方法调用委托给父代或 si金光闪闪的类。这对访问在类中被覆盖的继承方法 非常有用。搜索顺序与getattr()
使用的 相同,只是跳过了类型本身。
类型的__mro__
属性列出了由两个getattr()
和super()
所使用的方法的分辨率搜索顺序。属性 是动态的,只要继承层次更新为 ,就可以更改。
(...)
(复制,黑体字加)
例如说你定义类,如(从this question, where the MRO is discussed in more detail借用):
class F:
def __init__(self):
print('F%s'%super().__init__)
super().__init__()
class G:
def __init__(self):
print('G%s'%super().__init__)
super().__init__()
class H:
def __init__(self):
print('H%s'%super().__init__)
super().__init__()
class E(G,H):
def __init__(self):
print('E%s'%super().__init__)
super().__init__()
class D(E,F):
def __init__(self):
print('D%s'%super().__init__)
super().__init__()
class C(E,G):
def __init__(self):
print('C%s'%super().__init__)
super().__init__()
class B(C,H):
def __init__(self):
print('B%s'%super().__init__)
super().__init__()
class A(D,B,E):
def __init__(self):
print('A%s'%super().__init__)
super().__init__()
随后的A
的__mro__
是:
A.__mro__ == (A,D,B,C,E,G,H,F,object)
现在,如果我们拨打A()
,它会打印:
A<bound method D.__init__ of <__main__.A object at 0x7efefd8645c0>>
D<bound method B.__init__ of <__main__.A object at 0x7efefd8645c0>>
B<bound method C.__init__ of <__main__.A object at 0x7efefd8645c0>>
C<bound method E.__init__ of <__main__.A object at 0x7efefd8645c0>>
E<bound method G.__init__ of <__main__.A object at 0x7efefd8645c0>>
G<bound method H.__init__ of <__main__.A object at 0x7efefd8645c0>>
H<bound method F.__init__ of <__main__.A object at 0x7efefd8645c0>>
F<method-wrapper '__init__' of A object at 0x7efefd8645c0>
<__main__.A object at 0x7efefd8645c0>
因此它意味着在的A
上下文,并试图时获得__init__
在于:
- 的
A
super().__init__
是D.__init__
;
super().__init__
的D
是B.__init__
;
super().__init__
的B
是C.__init__
;
super().__init__
of C
is E.__init__
;
super().__init__
of E
is G.__init__
;
super().__init__
of G
is H.__init__
;
super().__init__
of H
is F.__init__
;和
super().__init__
的F
是object.__init__
。
注意这样说super()
不本身并不代表到父。例如D
的super()
是B
而B
不是D
的超类,所以它确实是取决于对象类型(不在类上)。
现在的D
情况下,__mro__
是:
D.__mro__ = (D,E,G,H,F,object)
如果我们构建一个D
但是我们得到:
D<bound method E.__init__ of <__main__.D object at 0x7efefd864630>>
E<bound method G.__init__ of <__main__.D object at 0x7efefd864630>>
G<bound method H.__init__ of <__main__.D object at 0x7efefd864630>>
H<bound method F.__init__ of <__main__.D object at 0x7efefd864630>>
F<method-wrapper '__init__' of D object at 0x7efefd864630>
所以在D
的背景下,认为:
super().__init__
的D
是E.__init__
;
super().__init__
of E
is G.__init__
;
super().__init__
of G
is H.__init__
;
super().__init__
of H
is F.__init__
;和
super().__init__
的F
是object.__init__
。
所以这里的D
的super()
导致E
(为__init__
)是不是在A
背景相同。
'super()'使用** MRO **解决呼叫... ... –
仅当您的子类有多个超类时,或者您可能在某些时候将您的子类更改为继承一个不同的超类。顺便说一句,“父类”不是通常的继承术语。 – khelwood
@khelwood:严格地说,这不是真的:如果你继承了一个具有多重继承的类,你的'super()'实际上可以委托给一个slibing,而不是父类。它只是返回'__mro__'中的下一行。 –