1、 super([type[, object-or-type]])
super() 在使用時至少傳遞一個參數,且這個參數必須是一個類。
通過super()獲取到的是一個代理對象,通過這個對象去查找父類或者兄弟類的方法。
2、super()不寫參數的情況

class Base: def __init__(self): print('Base.__init__') class A(Base): def __init__(self): super().__init__() print('A.__init__') class B(Base): def __init__(self): super().__init__() print('B.__init__') class C(Base): def __init__(self): super().__init__() print('C.__init__') class D(A, B, C): def __init__(self): super().__init__() # 等同於 super(D, self).__init__() print('D.__init__') D() print(D.mro())
結果:
Base.__init__ C.__init__ B.__init__ A.__init__ D.__init__ [<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.Base'>, <class 'object'>]
super() 在一個定義的類中使用時,可以不寫參數,Python會自動根據情況將兩個參數傳遞給super。
在Python3中的類都是新式類,廣度優先的查找順序,在定義一個類時就會生成一個MRO列表(經典類沒有MRO列表,深度優先),查找順序就是按照這個列表中的類的順序從左到右進行的。
3、super(type) 只傳遞一個參數的情況

class Base: def __init__(self): print('Base.__init__') class A(Base): def __init__(self): super().__init__() print('A.__init__') class B(Base): def __init__(self): super().__init__() print('B.__init__') class C(Base): def __init__(self): super().__init__() print('C.__init__') class D(A, B, C): def __init__(self): super(B).__init__() # 值傳遞一個參數 print('D.__init__') D() print(D.mro())
結果:
D.__init__ [<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.Base'>, <class 'object'>]
其他方法都沒有被調用。
super() 只傳遞一個參數時,是一個不綁定的對象,不綁定的話它的方法是不會有用的
4、super(type, obj) 傳遞一個類和一個對象的情況

class Base: def __init__(self): print('Base.__init__') class A(Base): def __init__(self): super().__init__() print('A.__init__') class B(Base): def __init__(self): super().__init__() print('B.__init__') class C(Base): def __init__(self): super().__init__() print('C.__init__') class D(A, B, C): def __init__(self): super(B, self).__init__() # self是B的子類D的實例 print('D.__init__') D() print(D.mro())
結果:
Base.__init__ C.__init__ D.__init__ [<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.Base'>, <class 'object'>]
super() 的參數為一個類和一個對象的時候,得到的是一個綁定的super對象。但是obj必須是type的實例或者是子類的實例。
從結果可以看出,只是查找了B類之后的類的方法,
即super()是根據第二個參數(obj)來計算MRO,根據順序查找第一個參數(類)之后的類的方法
5、super(type1, type2) 傳遞兩個類的情況

class Base: def __init__(self): print('Base.__init__') class A(Base): def __init__(self): super().__init__() print('A.__init__') class B(Base): def __init__(self): super().__init__() print('B.__init__') class C(Base): def __init__(self): super().__init__() print('C.__init__') class D(A, B, C): def __init__(self): super(B, D).__init__(self) # D是B的子類,並且需要傳遞一個參數 print('D.__init__') D() print(D.mro())
結果:
Base.__init__ C.__init__ D.__init__ [<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.Base'>, <class 'object'>]
super()傳遞兩個類type1和type2時,得到的也是一個綁定的super對象,但這需要type2是type1的子類,且如果調用的方法需要傳遞參數時,必須手動傳入參數,因為super()第二個參數是類時,得到的方法是函數類型的,使用時不存在自動傳參,第二個參數是對象時,得到的是綁定方法,可以自動傳參。
結果: