在看python高階程式設計這本書的時候,在講到super的時候,產生了一些疑惑,super在python中的用法跟其他的語言有一些不一樣的地方,在網上找了一些資料,發現基本上很少有文章能把我的疑惑講明白,其中這篇文章最有價值的地方是它講解了我們平時對super的正確使用方法。
首先看一段程式:
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())
這段程式的列印結果是:
mro: ['c', 'a', 'b', 'e', 'd', 'object']
c a b e d d b e d <__main__.c object at 0x1040340b8>
這段程式可以簡單演示super()的用法,比較簡單的概念是__mro__,它告訴我們某個類的繼承鏈資訊,生成這個鏈的原則有兩條:
要想理解上邊程式的列印結果,只需要知道super()其實它相當於super(cls, self),知道了這一點答案就很清晰了
當執行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了,因此列印結果是:
mro: ['c', 'a', 'b', 'e', 'd', 'object']
c a d b e d <__main__.c object at 0x1040340b8>
super()具有執行時特性,也就是說它的結果是動態計算出來的,利用這一點可以寫出擴充套件性比較好的程式,同時,從程式設計語義也更符合生活習慣。目前能夠總結的就是這樣。 python中的一些函式
最近一直在看opencv中白平衡的 遇到了一些python的函式,自己不熟悉,下面就這些零碎的知識點進行整理。strip v 剝光 剝去 服 python中strip 方法用於移除字串頭尾指定的字元 預設為空格 str.strip chars 例子 str 00000000this is strin...
python中演算法 python中的一些演算法
遞迴,尾遞迴 def fact n return fact iter n,1 def fact iter num,product if num 1 return product return fact iter num 1,num product 菲波列切數列 def fibo n if n 1 o...
python模組用法 Python中的一些模組用法
os模組 import os 1 path os.getcwd 獲取當前路徑 2 os.listdir path 列出當前目錄下的所有檔案和資料夾 3 os.path.split path 函式返回路徑的目錄名和檔名,其中path形如 c python25 abc.txt 4 os.path.spl...