天天看點

Learning Python Part IV 之 屬性繼承搜尋(Attribute Inheritance Search)

比起在例如C++、JAVA中,OOP在Python中了解和使用起來更簡單。作為一個動态類型程式設計語言,Python移除了很多的複雜和混亂文法,包括其他工具中的Clouds OOP。事實上,Python中的大部分OOP贅述都可以歸結為這個表達式:

object.attribute
           

之前我們已經用過這個表達式通路子產品的屬性、調用對象的方法等,對于一個由class語句産生的對象來說這個表達式在Python内是以搜尋開始的——它搜尋一個對象的相關樹,尋找屬性首次出現的地方,到類加入進來之後,之後的處理就可以用以下自然語言表述:

首先在object内尋找第一個出現的attribute,然後在這個類之上的所有類中尋找,按照從底向上從左到右的順序。
           

換句話說,取屬性就是樹搜尋。術語inheritance也适用,因為樹中低級的對象從更進階的對象繼承屬性。随着從底向上的不斷推進,在某種意義上來說,樹中的對象是所有在它父對象中定義的屬性的聯合體。

在Python中,我們在寫代碼的時候建立相關的對象樹,每次我們使用

object.attribute

表達式的時候,在運作時的确是從下到上的沿着樹搜尋屬性。

Learning Python Part IV 之 屬性繼承搜尋(Attribute Inheritance Search)

類和執行個體

在這個表中,有一個包含五個帶有變量标注的對象。所有對象都帶有屬性,等待被搜尋。更精确的講,這個樹是一個三個類對象(C1,C2,C3)加兩個執行個體對象的繼承搜尋樹。不過注意Python中的對象模型,類和由類産生的執行個體是兩個完全不同的對象類型:

  • 類:
    扮演一個執行個體工廠的角色,他們的屬性提供行為——資料和函數——這會被所有他們産生的執行個體所繼承。
               
  • 執行個體:
    在程式域内代表具體的items。他們的屬性記錄資料,并且這些資料随着不同的特定對象而不同。
               

依據搜尋樹,一個執行個體從它的類繼承屬性,而類從樹中在它之上的所有類中繼承屬性。

樹中類的細分

在表中,我們可以根據在樹中的相對位置的不同更加細化的分類。我們通常把在樹中位置高一點的類稱作(C2,C3)

superclasses

;位置低一點的類稱作

subclasses

。這些術語涉及到了在樹中的相對位置和角色。

superclasses

提供被所有

subclasses

共享的行為(behavior),但是因為搜尋是從底向上推進的,

subclasses

可能會覆寫在

superclasses

中定義的行為。

繼承搜尋舉例

因為上面的話在OOP中軟體定制化中是關鍵,讓我們擴充一下這個概念。設想我們建立一個表中的樹,然後:

這個代碼會引起繼承,因為這是一個

object.attribute

表達式,它開始了表中樹的搜尋——Python會在

I2

和之上的類中搜尋屬性

w

。确切的講,他會以下面的順序搜尋相關的對象:

I2,C1,C2,C3
           

然後會在第一個找到

w

的地方停下(或者沒找到的話抛出錯誤)。在這個例子中,直到搜尋到

C3

時才會找到

w

,因為隻有

C3

中才有

w

,用OOP術語講,

I2

C3

繼承屬性

w

這兩個執行個體從他們的類中繼承了4個屬性:w,x,y和z。其他的屬性引用在樹中會沿着不同的路徑尋找,例如:

  • I1.x 和 I2x都是在C1中找到x并停止應為C1比C2 更低
  • I1.y和I2.y都在C1中找到y因為隻有C1有y
  • I1.z和I2.z都在C2中找到z因為C2比C3更靠左
  • I2.name 直接在I2中找到name,完全不需要網上尋找

仔細品味上面的例子會了解在Python中繼承搜尋是如何運作的。

重定義

值得注意的是,C1在樹中更低級的地方重定義了屬性x,取代了C2之上的版本。這樣的重定義正是OOP中軟體定制化的核心——重定義取代屬性,C1很巧妙的定制化了從superclasses繼承的東西。