python中對象方法的定義很怪異,第一個參數一般都命名為self(相當于其它語言的this),用于傳遞對象本身,
有時候還會有一個參數cls(相當于類名,當直接調用類方法的時候使用)。
python2中super()的用法:
super(class,self).__init__()
python3中super()的用法:
super().__init__()
在類的繼承裡面super()非常常用, 它解決了子類調用父類方法的一些問題, 父類多次被調用時隻執行一次。
def super(cls, inst):
mro = inst.__class__.mro()
return mro[mro.index(cls) +1]
當使用 super(cls, inst) 時,Python 會在 inst 的類的 MRO 清單上搜尋 cls 的下一個類。
而檢視inst類的的MRO清單的方法就是:
類.mro() 或 類.__mro__ 或 inst.__class__.mro()
例如:當C是一個類的時候,獲得一個類的MRO的方法是
C.mro() 或 C.__mro__ 或 C().__class__.mro()
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5SM3ETM5kDNyEjMtEDOyQzMxMDOxcjM1ADMyAjMtETN2gDN38CX1ADMyAjMvwVM1YDO0czLcd2bsJ2Lc12bj5ycn9Gbi52YuAjMwIzZtl2Lc9CX6MHc0RHaiojIsJye.png)
執行過程:
當執行生成D的inst對象的時候,先執行Enter D
這個時候D類的MRO清單為[, , , , ]
當執行super(D,self) 就是在self對象的類的MRO清單中查找D的下一個父類。這個self是D類的執行個體對象inst。
而D類中的MRO清單中D的下一個父類是B。
例如:
1、super單繼承的時候:
class A:
def __init__(self):
self.n = 2
def add(self, m):
print('self is {0} @A.add'.format(self))
self.n += m
class B(A):
def __init__(self):
self.n = 3
def add(self, m):
print('self is {0} @B.add'.format(self))
super().add(m)
self.n += 3
b = B()
b.add(2)
print(b.n)
結果是什麼呢?
為什麼是8?
執行b.add(2)的時候,執行A中的add()函數,執行的時候這個時候的self是b這個執行個體,是以這個self.n是3
是以執行3+2=5
然後執行super的下一句5+3=8。
2、super多繼承的時候
#super的多繼承
class A:
def __init__(self):
self.n = 2
def add(self, m):
print('self is {0} @A.add'.format(self))
self.n += m
class B(A):
def __init__(self):
self.n = 3
def add(self, m):
print('self is {0} @B.add'.format(self))
super().add(m)
self.n += 3
class C(A):
def __init__(self):
self.n = 4
def add(self, m):
print('self is {0} @C.add'.format(self))
super().add(m)
self.n += 4
class D(B, C):
def __init__(self):
self.n = 5
def add(self, m):
print('self is {0} @D.add'.format(self))
super().add(m)
self.n += 5
d = D()
d.add(2)
print(d.n)
這個結果是什麼呢?
我認為是5+B.add+C.add+A.add+5=5+3+4+2+5=19
看下輸出的結果:
執行過程是什麼樣的呢?
詳細的代碼分析如下: