在看python高級編程這本書的時候,在講到super的時候,產生了一些疑惑,super在python中的用法跟其餘的語言有一些不同的地方,在網上找了一些資料,發現基本上不多有文章能把個人疑惑講明白,其中這篇文章最有價值的地方是它講解了咱們平時對super的正確使用方法。python
首先看一段程序:編程
class A: def __init__(self): print("A", end=" ") super().__init__() class E: def __init__(self): print("E", end=" ") super().__init__() class B(E): def __init__(self): print("B", end=" ") super().__init__() class D: def __init__(self): print("D", end=" ") super().__init__() class C(A, B, D): def __init__(self): print("C", end=" ") A.__init__(self) D.__init__(self) B.__init__(self) print("MRO:", [x.__name__ for x in C.__mro__]) print(C())
這段程序的打印結果是:ide
MRO: ['C', 'A', 'B', 'E', 'D', 'object'] C A B E D D B E D <__main__.C object at 0x1040340b8>
這段程序能夠簡單演示super()的用法,比較簡單的概念是__mro__,它告訴咱們某個類的繼承鏈信息,生成這個鏈的原則有兩條:wordpress
要想理解上邊程序的打印結果,只須要知道super()其實它至關於super(cls, self),知道了這一點答案就很清晰了code
當執行A.__init__(self)
這行代碼的時候,self指向了c實例對象,而後打印出A,當調用super().__init__()
這行代碼的時候,實際至關於super(A, self).__init__()
的調用, super(A, self)
的會在self.__mro__中查找排在A後邊的類,這樣就實現了繼承鏈的調用了。對象
其實到了這裏,咱們基本上能猜到super()的實現原理了,雖然看上去它像沒傳入參數同樣,其實否則,若是咱們改變參數,找到的父類是不一樣的。排序
咱們把上邊代碼中的A稍微改變一下:繼承
class A: def __init__(self): print("A", end=" ") super(D, self).__init__()
那麼在這裏super(D, self)
獲取的就是object了,所以打印結果是:get
MRO: ['C', 'A', 'B', 'E', 'D', 'object'] C A D B E D <__main__.C object at 0x1040340b8>
super()具備運行時特性,也就是說它的結果是動態計算出來的,利用這一點能夠寫出擴展性比較好的程序,同時,從編程語義也更符合生活習慣。目前可以總結的就是這樣。it