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__'中的下一行。 –