python和C++一樣坷剧,支持多繼承惰爬。概念雖然容易,但是困難的工作是如果子類調(diào)用一個自身沒有定義的屬性惫企,它是按照何種順序去到父類尋找呢撕瞧,尤其是眾多父類中有多個都包含該同名屬性。
classP1#(object):
? ? deffoo(self):
? ? ? ? print'p1-foo'
classP2#(object):
? ? deffoo(self):
? ? ? ?print'p2-foo'
? ? defbar(self):
? ? ? ? print'p2-bar'
classC1?(P1,P2):
? ? ?pass
classC2?(P1,P2):
? ? defbar(self):
? ? ? ? print'C2-bar'
classD(C1,C2):
? ? ?pass
對經(jīng)典類和新式類來說狞尔,屬性的查找順序是不同的〈园妫現(xiàn)在我們分別看一下經(jīng)典類和新式類兩種不同的表現(xiàn)
1、經(jīng)典類
d=D()
d.foo()#?輸出?p1-foo
d.bar()#?輸出?p2-bar
實例d調(diào)用foo()時沪么,搜索順序是 D => C1 => P1
實例d調(diào)用bar()時硼婿,搜索順序是 D => C1 => P1 => P2
換句話說,經(jīng)典類的搜索方式是按照“從左至右禽车,深度優(yōu)先”的方式去查找屬性寇漫。d先查找自身是否有foo方法,沒有則查找最近的父類C1里是否有該方法殉摔,如果沒有則繼續(xù)向上查找州胳,直到在P1中找到該方法,查找結(jié)束逸月。
2栓撞、新式類
使用新式類要去掉第一段代碼中的注釋
d=D()
d.foo()#?輸出?p1-foo
d.bar()#?輸出?c2-bar
實例d調(diào)用foo()時,搜索順序是 D => C1 => C2 => P1
實例d調(diào)用bar()時,搜索順序是 D => C1 => C2
可以看出瓤湘,新式類的搜索方式是采用“廣度優(yōu)先”的方式去查找屬性瓢颅。其實是 拓撲排序 。
拓撲排序 ? 就是每次取入度等于0的節(jié)點弛说,如果沒有特別復雜的繼承關(guān)系看起來就像是 BFS(廣度優(yōu)先)
可以調(diào)用類的__mro__屬性來查看查找順序
文章摘選自:http://2577885.blog.51cto.com/2567885/669322
拓撲排序:來自:https://songlee24.github.io/2015/05/07/topological-sorting/