Python多重繼承的異構構造器

2021-06-10 08:56:20 字數 1443 閱讀 1969

在python裡面,如果你使用上qt,sqlalchemy,twisted之類各種大型類庫時候,有時候多重繼承multiple inheritance是個簡單的解決方法,但是多重繼承的複雜性總容易造成誤解和疑惑。

一般「常識」說,使用super訪問父類的屬性/方法,這種說法在多重繼承裡面是不成立的,多重繼承的類並沒有父類的概念(there is no superclass in a mi world)。類似的部落格在過去幾年被人寫了無數遍了,因為過去版本裡面python官方文件對super的解釋非常有限而且有誤導解釋,直到2.6以後的文件,才詳細說明了super在單繼承和多繼承的兩種不同工作方式。當時苦逼的程式設計師甚至不得不去翻看python原始碼才搞清楚是什麼回事。以致幾年來很多人對python的多重繼承保持懷疑態度。

python多重繼承使用method resolution order的動態演算法來解決乙個方法名的呼叫順序,mro其實說來簡單,就是乙個深度優先的繼承列表,很易理解,但隨之來的是遇到互不相同的構造器__init__引數的問題。

class a(object):

def __init__(self, arg1):

print "init func in a, with arg1 '%s'" % arg1

super(a, self).__init__()

class b(object):

def __init__(self, arg1, arg2):

print "init func in b, with arg1'%s', arg2 '%s'" % (arg1, arg2)

super(b, self).__init__(arg1)

class c(b, a):

def __init__(self, arg1, arg2):

print "init func in c, with arg1'%s', arg2 '%s'" % (arg1, arg2)

super(c, self).__init__(arg1, arg2)

print c.__mro__

c = c("a", "b")

執行結果:

init func in c, with arg1'a', arg2 'b'

init func in b, with arg1'a', arg2 'b'

init func in a, with arg1 'a'

可見幾個類的構造器的執行順序正是mro列表的順序。重點是多重繼承的各個類的構造器__init__之所以能夠執行,是因為每個構造器裡面都有一句super(),這個super完成mro列表中

下乙個類的構造器的呼叫

。可是有一點,怎麼也想不通啊,a和b類在c類中初始化,怎麼a和b共乙個引數「a」?如果兩個建構函式需要的引數型別不一樣呢?我得再細想想

Python多重繼承的異構構造器

在python裡面,如果你使用上qt,sqlalchemy,twisted之類各種大型類庫時候,有時候多重繼承multiple inheritance是個簡單的解決方法,但是多重繼承的複雜性總容易造成誤解和疑惑。一般 常識 說,使用super訪問父類的屬性 方法,這種說法在多重繼承裡面是不成立的,多...

python的多重繼承

在設計類的繼承關係時,通常,主線都是單一繼承下來的,如果需要 混入 額外的功能,通過多重繼承就可以實現,這種設計通常稱之為mixin。class animal object pass class mammal animal pass class runnable object def run sel...

python的多重繼承

python和c 一樣,支援多繼承。概念雖然容易,但是困難的工作是如果子類呼叫乙個自身沒有定義的屬性,它是按照何種順序去到父類尋找呢,尤其是眾多父類中有多個都包含該同名屬性。對經典類和新式類來說,屬性的查詢順序是不同的。現在我們分別看一下經典類和新式類兩種不同的表現 經典類 usr bin pyth...