python中多繼承的問題 比較C 的多繼承

2021-07-07 06:00:35 字數 3997 閱讀 9896

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...