python繼承與super 函式

2021-10-09 09:58:42 字數 3722 閱讀 7378

super() 在使用時至少傳遞乙個引數,且這個引數必須是乙個類。

通過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__

[, , , , , ]

super() 在乙個定義的類中使用時,可以不寫引數,python會自動根據情況將兩個引數傳遞給super

在python3中的類都是新式類,廣度優先的查詢順序,在定義乙個類時就會生成乙個mro列表(經典類沒有mro列表,深度優先),查詢順序就是按照這個列表中的類的順序從左到右進行的。

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__

[, , , , , ]

process finished with exit code 0

其他方法都沒有被呼叫。

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(b, self).__init__() # self是d的例項,同時也是b的子類例項

print('d.__init__')

d()print(d.mro())

結果:

base.__init__

c.__init__

d.__init__

[, , , , , ]

process finished with exit code 0

super() 的引數為乙個類和乙個物件的時候,得到的是乙個繫結的super物件。但是obj必須是type的例項或者是子類的例項。

從結果可以看出,只是查詢了b類之後的類的方法,

super()是根據第二個引數(obj)來計算mro,根據順序查詢第乙個引數(類)之後的類的方法

class base:

def __init__(self):

print('base.__init__')

def funcbase(self):

print("base class")

class a(base):

def __init__(self):

super().__init__()

print('a.__init__')

def funca(self):

print("a class")

class b(base):

def __init__(self):

super().__init__()

print('b.__init__')

def funcb(self):

print("b class")

class c(base):

def __init__(self):

super().__init__()

print('c.__init__')

def funcc(self):

print("c class")

class d(a, b, c):

def __init__(self):

super(b, d).__init__(self) # self是d的例項,同時也是b的子類例項

print('d.__init__')

def funcd(self):

print("d class")

d = d()

print(d.mro())

結果:

base.__init__

c.__init__

d.__init__

[, , , , , ]

process finished with exit code 0

super()傳遞兩個類type1和type2時,得到的也是乙個繫結的super物件,但這需要type2是type1的子類,且如果呼叫的方法需要傳遞引數時,必須手動傳入引數,因為super()第二個引數是類時,得到的方法是函式型別的,使用時不存在自動傳參,第二個引數是物件時,得到的是繫結方法,可以自動傳參。

super與多繼承

1 super 1.1 super是乙個內建類,可以參考 builtin 中的 super 類 class super object def init self,type1,type2 none known special case of super.init super type,obj boun...

Python中多繼承與super 用法

python類分為兩種,一種叫經典類,一種叫新式類。兩種都支援多繼承。考慮一種情形,b繼承於a,c繼承於a和b,但c需要呼叫父類的init 函式時,前者會導致父類a的init 函式被呼叫2次,這是不希望看到的。而且子類要顯式地指定父類,不符合dry原則。經典類 class a def init se...

python多重繼承和super

本文只說現在python繼承順序採用的c3演算法,只要弄明白c3演算法,你就知道super函式的工作原理。c3演算法的規則如下 從底層開始,選擇入邊為零的點。從左到右。深度探索。但受限與 規則。每乙個類都可以用mro函式檢視自己的繼承順序 例子1.菱形繼承1 分析 規則。得到a類,去掉a類以後,入邊...