python的多繼承類是通過mro的方式來保證各個父類的函式被逐一呼叫,而且保證每個父類函式都只被呼叫一次
和c++不同的是:
1.如果子類中沒有作顯示呼叫!並且父類的構造__init__()中不需要傳入額外的引數。那麼,很明顯的,父類的__init__不會被呼叫
class a():
def __init__(self):
print('a')
class b(a):
def __init__(self):
print('b')
b = b()
很明顯的,只輸出'b'
2.在多繼承當中,python對於多繼承類的呼叫機制是 1。當某個類d多繼承類b,c,e。那麼走b的構造的時候
(1)若b、c、e的父類不同!也就是不出現重複繼承的問題!則按照正常的順序d構造->b->b的父類,c->c的父類 d
如下所示,他們各不影響
class a:
def __init__(self):
print('a')
class s:
def __init__(self):
print('s')
print('l_s')
class m:
def __init__(self):
print('m')
print('l_m')
class b(a):
def __init__(self):
print('b')
super(b,self).__init__()
print('l_b')
class c(s):
def __init__(self):
print('c')
super(c,self).__init__()
print('l_c')
class d(m):
def __init__(self):
print('d')
super(d,self).__init__()
print('l_d')
class e(b,c,d):
def __init__(self):
b.__init__(self)
c.__init__(self)
d.__init__(self)
print('l_e')
d = e()
結果!
b
al_bcs
l_sl_cdm
l_ml_d
l_e
(2).若b、c、e的父類有乙個或者多個是相同的,則父類不相同的,走到父類,父類相同的,待都走完再走父類
若c、e父類相同,b與ce父類不同,則先走b->b的父類->c->e->(ce的父類)
(ps:關於原理。。真實很暈。。這時候我想到了c語言的多繼承問題)
他們的記憶體圖假設是這樣的: b繼承m mb
c繼承a ac
e繼承a ae
如果用c++虛繼承的概念來理解:( *pa c *pa e a) *pa指向a ,那就不難理解!為什麼是c->e->a了!
class a:
def __init__(self):
print('a')
class s:
def __init__(self):
print('s')
print('l_s')
class m:
def __init__(self):
print('m')
print('l_m')
class b(s):
def __init__(self):
print('b')
super(b,self).__init__()
print('l_b')
class c(a):
def __init__(self):
print('c')
super(c,self).__init__()
print('l_c')
class d(a):
def __init__(self):
print('d')
super(d,self).__init__()
print('l_d')
class e(b,c,d):
def __init__(self):
b.__init__(self)
c.__init__(self)
d.__init__(self)
print('l_e')
d = e()
輸出:
b
sl_s
l_bcda
l_dl_cda
l_dl_e
3.python提供了一種機制,super()來避免這種重複的問題!類似於虛繼承:
class e(b,c,d):
def __init__(self):super().__init__()print('l_e')
d = e()
輸出:b
sl_s
l_bps:(納尼!咋回事!!!!! cd呢)
原來。。根據以上的路線,為了避免基類的重複,他只會走到類的頂端最上層就停下!
如果呼叫e繼承cd,那麼走c的時候,c->d->a的時候就終止了!不會繼續走
class a:
def __init__(self):
print('a')
class s:
def __init__(self):
print('s')
print('l_s')
class m:
def __init__(self):
print('m')
print('l_m')
class b(s):
def __init__(self):
print('b')
super(b,self).__init__()
print('l_b')
class c(a):
def __init__(self):
print('c')
super(c,self).__init__()
print('l_c')
class d(a):
def __init__(self):
print('d')
super(d,self).__init__()
print('l_d')
class e(c,d):
def __init__(self):
super(e,self).__init__()
d = e()
輸出
cda
l_dl_c總結(摘自
1. super並不是乙個函式,是乙個類名,形如super(b, self)事實上呼叫了super類的初始化函式,
產生了乙個super物件;
2. super類的初始化函式並沒有做什麼特殊的操作,只是簡單記錄了類型別和具體例項;
3. super(b, self).func的呼叫並不是用於呼叫當前類的父類的func函式;
4. python的多繼承類是通過mro的方式來保證各個父類的函式被逐一呼叫,而且保證每個父類函式
只呼叫一次(如果每個類都使用super);
5. 混用super類和非繫結的函式是乙個危險行為,這可能導致應該呼叫的父類函式沒有呼叫或者一
個父類函式被呼叫多次。
Python中的多繼承
python和c 一樣,支援多繼承。概念雖然容易,但是困難的工作是如果子類呼叫乙個自身沒有定義的屬性,它是按照何種順序去到父類尋找呢,尤其是眾多父類中有多個都包含該同名屬性。class p1 object deffoo self print p1 foo class p2 object deffoo...
python中的多繼承
一 介紹 python同樣有限的支援多繼承形式。多繼承的類定義形如下例 class derivedclassname base1,base2,base3 需要注意圓括號中父類的順序,若是父類中有相同的方法名,而在子類使用時未指定,python從左至右搜尋 即方法在子類中未找到時,從左到右查詢父類中是...
Python中的多繼承
coding utf8 1.多繼承 子類有多個父類 class human def init self,self.defp self print 這是human的方法 class person def init self,name self.name name defp self print 這是p...