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())
super() 在乙個定義的類中使用時,可以不寫引數,python會自動根據情況將兩個引數傳遞給super。base.__init__
c.__init__
b.__init__
a.__init__
d.__init__
[, , , , , ]
在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())
super() 的引數為乙個類和乙個物件的時候,得到的是乙個繫結的super物件。但是obj必須是type的例項或者是子類的例項。base.__init__
c.__init__
d.__init__
[, , , , , ]
process finished with exit code 0
從結果可以看出,只是查詢了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())
super()傳遞兩個類type1和type2時,得到的也是乙個繫結的super物件,但這需要type2是type1的子類,且如果呼叫的方法需要傳遞引數時,必須手動傳入引數,因為super()第二個引數是類時,得到的方法是函式型別的,使用時不存在自動傳參,第二個引數是物件時,得到的是繫結方法,可以自動傳參。base.__init__
c.__init__
d.__init__
[, , , , , ]
process finished with exit code 0
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類以後,入邊...