在python中一切都是物件,每個物件都有乙個唯一的不可變的id(通過id函式查詢)。把乙個名字和乙個id關聯起來,就可以通過這個名字檢索到這個物件。如果乙個物件a持有另乙個物件b的id,那麼檢索到a之後就可以檢索到b,我們就說存在乙個a到b的導航。這種導航關係使得python中所有物件之間形成了乙個複雜的網路結構。
python程式的執行包括:
1. 修改這個網路結構;
2. 執行有***的**物件(code object或者說bytecode,見python language reference 3.2)
(***是指影響python虛擬機器之外的裝置,這些**都是用c或者別的語言寫的,python寫的**只能完成第一步的功能。print語句除外。)
python物件之間有兩種導航關係:繼承關係和型別關係,是python中最基本的關係。型別關係說明乙個物件是通過哪個物件建立的;繼承關係說明物件之間的父子關係,這種父子關係在名字的解析過程中起到作用。這裡我首先說new style類之間的這兩種關係,掌握了new style類的關係後,再來說明classic類就容易了。
首先需要說明一下的是內建模組中的type是什麼。大家都知道type可以用來判斷乙個物件的型別,好像是乙個函式。實際上在2.2中type是乙個類,而且不是普通的類,是乙個可以建立類的類,稱為元類。你執行type(type)試一下,列印的是
。type類是python型別系統的核心。用type作為乙個判斷型別的函式使用是比較特殊的情況,或許是由歷史原因造成的,用typeof或許更合適。
如何構造乙個型別
你肯定知道是用class語句。但是實際上,在python核心看來,只有一種方式,那就是呼叫type的建構函式(因為type是乙個型別)。當執行:
class a(object):
def f(self): print 1
python解析器就會執行如下**所示功能:
def f(self): print 1
a=type('a', (object,), ) # 引數為(名字, 父類tuple,成員dict)
del f
兩者效果幾乎是一樣的,你可以試一下。
型別關係的確定除了使用type之外,還可以使用__class__屬性。如:
class a(object): pass
a=a()
a.__class__ # 'class __main__.a'
a.__class__ # 'type
'
type.__class__ # 'type
'
type.__class__.__class__ # 'type
'
type.__class__ is type.__class.__class__ # true
繼承關係
繼承關係只發生在型別之間,繼承關係構成乙個有向圖。所有的型別都是從object繼承來的。「所有的」當然也包括type。object的父類還是object。object作為乙個型別物件也是有其型別的,這個型別就是type。所以object和type之間的關係就好比先有雞還是先有蛋的問題了:type是從object繼承的(繼承關係);object是由type生成的(型別關係)。通過issubclass或者__bases__屬性來判斷兩個類之間的繼承關係。
那麼從type繼承意味著什麼呢?那意味著這個類的型別是type,同時父類也是type。但是這種做法在一般的程式設計中是沒有什麼意義的(卻是meta programmming的核心)。因為一般都用class語句,而不是通過呼叫type的建構函式來建立型別物件。為了說明語法還是舉個例子:
class mytype(type): pass
a=mytype('a', (object,), {}) #
del f
a.__class__ # class '__main__.mytype',元類為mytype
mytype.__class__ # 'type
'
在用class定義乙個類時,會間接呼叫type的建構函式。但是通過設定__metaclass__屬性,可以不去呼叫type,而是呼叫type的子類。如:
class a(object):
__metaclass__ = mytype
a.__class__ # class '__main__.mytype' ,和上面的方式結果一樣。
由此,python物件的型別關係組成了乙個樹型結構,其中type處於樹的根部,由type或者type的子類構造的型別,包括class定義的類(間接呼叫type),呼叫type、type的子類建構函式建立的類,int list等系統定義型別處於中間節點,葉節點為instance物件。type本身的型別是什麼呢?還是type。這和根目錄的父目錄還是根目錄是一樣的。
classic類不同於new style類的地方就是當用class建立乙個類時,不是間接呼叫type,而是間接呼叫types.classtype,而types.classtype是由type建立的。
class a: pass
type(a) # type 'classobj' ,注意沒有__class__屬性。
type(a) is types.classtype # true
types.classtype.__class__ # 'type'
Python中型別關係和繼承關係例項詳解
如果乙個物件a持有另乙個物件b的id,那麼檢索到a之後就可以檢索到b,我們就說存在乙個a到b的導航。這種導航關係使程式設計客棧得python中所有物件之間形成了乙個複雜的網路結構。python程式的執行包括 1.修改這個網路結構 2.執行有 的 物件 code object或者說bytecode,見...
Java泛型 繼承中型別變數的關係
通過例子來看泛型類在繼承中過程中型別變數應該具有怎樣的關係。首先給出幾個輔助類 package generic public class animal package generic public class person extends animal public string getname p...
python的多繼承關係
python和c 一樣,支援多繼承。概念雖然容易,但是困難的工作是如果子類呼叫乙個自身沒有定義的屬性,它是按照何種順序去到父類尋找呢,尤其是眾多父類中有多個都包含該同名屬性。class p1 object deffoo self print p1 foo class p2 object deffoo...