3 回答

TA貢獻1809條經驗 獲得超8個贊
考慮如何實例化:C
c = C(a=3, b=5, c=9)
C.__init__
獲取所有關鍵字參數,但僅將關鍵字參數用于其自己的參數。其余的將傳遞給鏈中的下一個方法。在本例中,即 ,它“拉出”的參數并傳遞給 。 使用它并將(現在為空的)關鍵字參數集傳遞給下一個方法 。由于所有關鍵字參數都已“聲明”并由其他類處理,因此會成功。c
__init__
A.__init__
a
b
B.__init__
B
object.__init__
object.__init__
由于 MRO 的構造方式,正確使用的類保證在調用時集體為空。super()
**kwargs
object.__init__

TA貢獻1777條經驗 獲得超3個贊
由于方法解析順序為 ,可以按以下方式定義嗎?(__main__.C, __main__.A, __main__.B, object)class B
否,因為這樣會失?。?/p>
class D:
def __init__(self, d, **kwargs):
self.d = d
super().__init__(**kwargs)
class E(C, D):
def __init__(self, e, **kwargs):
self.e = e
super().__init__(**kwargs)
的 MRO 是 ,所以必須調用,否則不會被調用。E(E, C, A, B, D, object)Bsuper().__init__D.__init__
難道不是多余的,因為任何盈余傳遞到都會傳遞到,提高?super().__init__(**kwargs)class BkwargsCobject
不,因為在上面的例子中,盈余將流向。但即使沒有這個,當你調用一個參數太多構造函數時,引發錯誤也不是多余的;最好有一條錯誤消息通知您不正確的代碼,而不是讓錯誤未被發現。kwargsD.__init__
這是否是如果被定義為而不是?Cclass C(B, A)class C(A, B)
從某種意義上說,當然;但實際上,它是在任何類層次結構中發生的保護措施,只要層次結構中的其他類遵循相同的調用規則。Bsuper().__init__(**kwargs)

TA貢獻1820條經驗 獲得超2個贊
在這個例子中,如果它像你說的那樣定義(第1點)并且是原樣的(并且沒有其他用途),那么它的工作原理是一樣的。BC
至于第2點:如果還剩下關鍵字參數,那么對構造函數的調用確實會失敗,例如:super()
c = C(a=1, b=2, c=3, d=4)
# -> TypeError: object.__init__() takes exactly one argument (the instance to initialize)
由于該類(最初)是編寫的,因此如果像您所說的那樣以相反的順序使用,或者如果有一個(或)多個超類(es),也是可以的,例如:B
class D:
def __init__(self, d, **kwargs):
super().__init__(**kwargs)
self.d = d
class C(A,B,D):
...
添加回答
舉報