C3演算法 和 super

2021-09-19 11:00:40 字數 3465 閱讀 9414

一. python的繼承  多繼承

子類繼承父類. 

繼承是為了節省開發時間.提高開發效率 **得到了重(chong)用 乙個類可以擁有多個父類

lass shen_xian:  #

定義乙個神仙類

def fei(self): #

神仙類有乙個方法 可以飛

print('

神仙都會飛')

class monkey: #

定義乙個猴子類

def chitao(self): #

猴子有乙個方法 可以吃桃子

print('

猴子喜歡吃桃')

class sunwukong(monkey,shen_xian): #

物件繼承猴子和神仙的型別

pass

sxz = sunwukong() #

例項化乙個孫悟空物件

sxz.chitao() #

會吃桃子

sxz.fei() #

會飛

多繼承用起來簡單 但是存在乙個問題 當父類**現重名方法時 就涉及到查詢父類方法中的問題 也即mro(method resolution order)

二. 經典類的mro

在python2中存在兩種類 

經典類 : 在python 2.2 之前 一直使用的是 經典類 

新式類 : 在2.2之後 出現了新式類 特點是 基類的根是object

python 3 

只有新式類  如果基類誰都不繼承 那麼會預設繼承object

經典類的mro 深度優先遍歷 例如 快遞員送雞蛋 :

肯定是按照123456順序來送 即每次都是最左邊 找完撤回到分叉口繼續往裡找(從左往右,一條道跑到黑,然後撤回繼續一條道跑到黑) 即深度優先遍歷   如果 142356 就是廣度優先遍歷

三. 新式類的mro, c3(重點, 難點)  可以通過 類名.__mro__ 獲取到類的mro資訊

即print(類名.__mro__) 就可以獲取到

python中的新式類的mro都是用 c3演算法來完成的

筆試的時候肯定會考

新式類中摒棄了(部分). c3演算法   

如果繼承關係沒有菱形繼承(深度優先)

如果有菱形:使用c3演算法來計算mro 

三. super

super()可以執行 mro中的下乙個父類的方法 通常super()有兩個使用的地方 :

1 . 可以訪問父類的構造方法

2 . 當子類方法想呼叫父類(mro)中的方法 

先看第一種

class

foo:

def__init__

(self,a,b,c):

self.a =a

self.b =b

self.c =c

class

bar(foo):

def__init__

(self,a,b,c,d):

super().

__init__

(a,b,c)

self.d =d

b = bar(1,2,3,4)

print(b.__dict__) #

這樣就方便了子類 不需要寫那麼多了

第二種 

class

foo:

deffunc1(self):

super().func1()

#此時找的是mro順序中下乙個類的func1()方法 實際到這就會報錯 根本不會執行

#因為 foo 中沒有func1方法 繼承的obj中也沒有func1()方法

print('

我的老家,就住在這個屯')

class

bar:

deffunc(self):

print('

你的老家,不在這個屯')

class

ku(foo,bar):

deffunc1(self):

super().func1()

print('

它的老家,不知道在哪個屯')

k = ku() #

先看mro ku , foo, bar ,object

k.func1()

k2 = foo() #

此時的mro foo , object 都沒有func1 因此會報錯 如果這樣寫一開始就會報錯 就不會執行到這才報錯

k2.func1()

五. 一道面試題

#

mro + super 面試題

class

init:

def__init__

(self,v):

print('

init')

self.val =v

class

add2(init):

def__init__

(self,val):

print('

add2')

super(add2,self).

__init__

(val)

print

(self.val)

self.val += 2

class

mult(init):

def__init__

(self,val):

print('

mult')

super(mult,self).

__init__

(val)

self.val *= 5

class

haha(init):

def__init__

(self,val):

print('哈哈'

) super(haha,self).

__init__

(val)

self.val /= 5

class

pro(add2,mult,haha):

pass

class

incr(pro):

def__init__

(self, val):

super(incr, self).

__init__

(val)

self.val += 1p = incr(5)

print

(p.val)

c = add2(2)

print(c.val)

view code

結論 : 不管super()寫在哪. 在哪執行,一定先找到mro列表.根據mro列表的順序往下找 否則都是錯的.

posted @

2018-09-30 12:36

你沒有想象的那麼重要 閱讀(

...)

編輯收藏

mro和c3 演算法

mro案例 class a pass class b a pass class c a pass class d b,c pass class e c,a pass class f d,e pass class g e pass class h g,f pass 計算方法 先將每乙個類的繼承mro,...

python之路 MRO和C3演算法

多繼承的一種方法,一種查詢的順序 在python3 裡面是一種新類式mro 需要用都的是c3演算法 class a pass class b a pass class c a pass class d b,c pass class e c,a pass class f d,e pass class ...

多繼承c3演算法

一.mro mro即 method resolution order 方法解釋順序 主要用於在多繼承時判斷屬性的路徑 來自於哪個類 print 類.mro 得到屬性路徑按繼承順序 在python2.2版本中,演算法基本思想是根據每個祖先類的繼承結構,編譯出一張列表,包括搜尋到的類,按策略刪除重複的。...