python多繼承(新式類)一


最近在學習python的多重繼承。

先來了解下多重繼承的概念,所謂多重繼承,是指python的類可以有兩個以上父類,也即有類A,類B,類C,C同時繼承類A與類B,此時C中可以使用A與B中的屬性與方法。那么問題來了,如果A與B中具有相同名字的方法,這個時候python怎么調用的會是哪個方法呢?

 

舉個例子:

class A(object):
  def __init__(self):
   pass

  def foo(self):

    print 'A foo'

class B(object):
  def __init__(self):
   pass

  def foo(self):

    print 'B foo'

class C(A,B):

 def __init__(self):

    pass

 

 

testc = C()

testc.foo()

 

實際上打印出來的信息是 A foo,這就說明了調用的是A中的方法。其實在python2.2之后,多繼承中基類的尋找順序是一種廣度優先算法,稱之為C3的算法(后續博客我會簡單介紹下C3算法)。而python2.2之前,使用的是深度優先算法來尋找基類方法。在類C的繼承關系中,按照廣度優先算法,則會先找到靠近C的基類A,在A中找到foo方法之后,就直接返回了,因此即使后面的基類B中也有foo方法,但是這里不會引用它。

 

更加清晰的多繼承例子:

class A(object):
    def foo(self):
        print 'A foo'
        
class B(object):
    def foo(self):
        print 'B foo'
    def bar(self):
        print 'B bar'
        
class C1(A,B):
    pass
    
class C2(A,B):
    def bar(self):
        print 'C2-bar'
        
class D(C1,C2):
    pass 
    

if __name__ =='__main__':
print D.__mro__ #只有新式類有__mro__屬性,告訴查找順序是怎樣的 d
=D() d.foo() d.bar()

執行的結果為:

(<class '__main__.D'>, <class '__main__.C1'>, <class '__main__.C2'>, <class '__main__.A'>, <class '__main__.B'>, <type 'object'>)

A foo (實際上搜索順序為D=>C1=>A)
C2 bar(實際上搜索順序為D=>C1=>C2)

可以看到,foo找到的是A類中的方法,bar找到的是C2中的方法。

 

其實新式類的搜索方法是采用了“廣度優先”的方式去查找屬性。

只有新式類有__mro__屬性,該屬性標記了python繼承層次中父類查找的順序,python多重繼承機制中就是按照__mro__的順序進行查找,一旦找到對應屬性,則查找馬上返回。

經過上面的__mro__輸出可以發現,D類的繼承查找路徑為:D=>C1=>C2=>A=>B=>object,通過該查找路徑,foo方法將會調用A的foo方法,、bar方法將調用C2的方法,通過實際實驗調用,查看輸出內容確實與__mro__順序一樣。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM