1. 程式人生 > 其它 >python super()函式有無引數的呼叫

python super()函式有無引數的呼叫

一、類的繼承中,子類物件初始化
下方的init都是__init__只不過markdown語法把他們變成了加粗
情況一:子類需要自動呼叫父類的方法:子類不重寫__init__()方法,例項化子類後,會自動呼叫父類的 init() 的方法。
情況二:子類不需要自動呼叫父類的方法:子類重寫__init__()方法,例項化子類後,將不會自動呼叫父類的 init() 的方法。
情況三:子類重寫 init() 方法又需要呼叫父類的方法,這時候就需要顯式地呼叫父類的 init() 方法。

呼叫父類的 init() 方法,有兩種方式:一種是直接使用 父類名. init() ;一種是使用 super(). init

()。
父類名. init() 這種方式,更加直接,更加定向地去呼叫對應的 init() 函式。但是可能會遇到重複呼叫的問題,甚至可能會進入死迴圈。


mro 可以返回子類中繼承父類的順序
mro 的順序基本原則就是:在避免同一類被呼叫多次的前提下,使用廣度優先和從左到右的原則去尋找需要的屬性和方法。
其實呼叫super函式返回的形式有點像遞迴==>super函式

下方是無引數的呼叫


class A():
    def __init__(self): 
        print("進入A…") 
        print("離開A…")
 
class G():
    def __init__(self):
        print("進入G…")
        super().__init__() #他這個類呼叫總父類object,這個呼叫才是呼叫D的關鍵吧
        print("離開G…")
        
class B(A):
    def __init__(self):
        print("進入B…")
        super().__init__() # 呼叫A
        print("離開B…")
        
class C(A):
    def __init__(self):
        print("進入C…")
        super().__init__() # 呼叫A
        print("離開C…")
 
class D(B, C):
    def __init__(self):
        print("進入D…") # 這裡輸出的關鍵點在於D中並沒有呼叫父類 super().__init__,呼叫G由於G中沒有super().__init__就逐層返回,所以就沒有執行離開D…
        print("離開D…")
 
class E(G):
    def __init__(self):
        print("進入E…")
        super().__init__() # 呼叫G;2次super().__init__下次就直接呼叫G麼
        print("離開E…")
 
class F(E,D):
    def __init__(self):
        print("進入F…")
        super().__init__() # 呼叫G B C A
        print("離開F…")        
 # __mro__ 的順序基本原則就是:在避免同一類被呼叫多次的前提下,使用廣度優先和從左到右的原則去尋找需要的屬性和方法。
print(F.__mro__) # 子類中繼承父類的順序
d = F()

有引數的呼叫

使用含引數的 super() 呼叫父類的初始化函式 init(),使用引數可以指定父類
實際上,使用 super 的時候也可以不完全按照 mro() 列表執行。因為 super 有兩個引數,第一個引數是父類名,第二個引數是例項化引數self,可以根據第一個引數跳躍去執行對應類的 init()。

class A():
    def __init__(self):
        print("進入A…")
        print("離開A…")

class G():
    def __init__(self):
        print("進入G…")
        print("離開G…")
        
class B(A):
    def __init__(self):
        print("進入B…")
        super(C,self).__init__() # 困惑點:這裡為啥先進入C,不應該先進入B,在進入C麼
        print("離開B…")
        
class C(A):
    def __init__(self):
        print("進入C…")
        super(D,self).__init__()
        print("離開C…")

class D(B, C):
    def __init__(self):
        print("進入D…")
        super().__init__()
        #super(A,self).__init__()
        print("離開D…")

class E(G):
    def __init__(self):
        print("進入E…")
        #super().__init__()
        super(B,self).__init__() #  對繼承自父類的屬性進行初始化
        # 比如這裡是先找到B,然後把類B的物件self轉化為類B的物件,再由被轉化的類B的物件呼叫__init__()函式
        print("離開E…")

class F(E,D):
    def __init__(self):
        print("進入F…")
        super().__init__()
        #super(G,self).__init__()
        print("離開F…")        
print(F.__mro__)
d = F()
努力拼搏吧,不要害怕,不要去規劃,不要迷茫。但你一定要在路上一直的走下去,儘管可能停滯不前,但也要走。