比起在例如C++、JAVA中,OOP在Python中了解和使用起來更簡單。作為一個動态類型程式設計語言,Python移除了很多的複雜和混亂文法,包括其他工具中的Clouds OOP。事實上,Python中的大部分OOP贅述都可以歸結為這個表達式:
object.attribute
之前我們已經用過這個表達式通路子產品的屬性、調用對象的方法等,對于一個由class語句産生的對象來說這個表達式在Python内是以搜尋開始的——它搜尋一個對象的相關樹,尋找屬性首次出現的地方,到類加入進來之後,之後的處理就可以用以下自然語言表述:
首先在object内尋找第一個出現的attribute,然後在這個類之上的所有類中尋找,按照從底向上從左到右的順序。
換句話說,取屬性就是樹搜尋。術語inheritance也适用,因為樹中低級的對象從更進階的對象繼承屬性。随着從底向上的不斷推進,在某種意義上來說,樹中的對象是所有在它父對象中定義的屬性的聯合體。
在Python中,我們在寫代碼的時候建立相關的對象樹,每次我們使用
object.attribute
表達式的時候,在運作時的确是從下到上的沿着樹搜尋屬性。
類和執行個體
在這個表中,有一個包含五個帶有變量标注的對象。所有對象都帶有屬性,等待被搜尋。更精确的講,這個樹是一個三個類對象(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繼承的東西。