轉載:Python中的new style class機制實現

1.Python中的對象模型
python中所有東西都是對象

class對象:表示Python內置的類型和定義的類型
instance對象(實例對象):表示由class對象創建的實例

1.1 對象間的關係
is-kind-of關係:對應於面向對象中的基類與子類之間的關係
is-instance-of關係:對應於面向對象中類與實例之間的關係

<class A>表示名爲A的class對象
<instance a>表示名爲a的instance對象
class A 定義了一個名爲A的class
class 對象表示在Python中的實現

通過對象的__class__屬性或Python內置的type方法可以探測一個對象和哪個對象存在is-instance-of關係
通過對象的__bases__屬性可可以探測一個對象和哪個對象存在is-kind-of關係
通過內置方法issubclass和isinstanceof判斷兩個對象間是否存在何種關係

複製代碼
>>> class A(object): //A是類對象
... pass
...
>>> a=A() //a是實例對象
>>> a.__class__ //a是A的實例
<class '__main__.A'>
>>> type(a)
<class '__main__.A'>
>>> A.__class__ //類對象A是type的實例
<type 'type'>
>>> type(A)
<type 'type'>
>>> object.__class__ //類對象object是type的實例
<type 'type'>
>>> type(object)
<type 'type'>
>>> A.__base__ //類對象A的基類是object
<type 'object'>
>>> object.__bases__
()
>>> a.__bases__ //a是實例對象,不是類對象
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute '__bases__'
>>> isinstance(a,A)
True
>>> issubclass(A,object)
True
>>>

<type 'type'>屬於Python中的一類特殊的class對象,這種特殊的class對象能夠成爲其他class對象的type。這種特殊的class對象稱爲metaclass對象
>>> object.__class__
<type 'type'>
>>> type.__class__
<type 'type'>
>>> type.__bases__
(<type 'object'>,)
>>> int.__class__
<type 'type'>
>>> int.__bases__
(<type 'object'>,)
>>> dict.__class__
<type 'type'>
>>> dict.__bases__
(<type 'object'>,)
複製代碼

任何一個對象都有一個type,可以通過對象的__class__屬性獲得
任何一個instance對象的type都是一個class對象,而任何一個class對象的type都是metaclass對象
任何一個class對象都直接或間接與<type 'object'>對象之間存在is-kind-of關係,包括<type 'type'>

2 從type對象到class對象
可調用性(callable)
只要一個對象對應的class對象中實現了"__call__"操作,也就是說在Python內部的PyTypeObject中,tp_call不爲空
在Python中,所謂"調用",就是執行對象的type所對應的class對象的tp_call操作
一個對象是否可調用並不是在編譯期能確定的,必須是在運行時才能在PyObject_CallFunctionObjArgs中確定
2.1 處理基類和type信息
對於指定了tp_base的內置class對象,當然就使用指定的基類,而對於沒有指定的tp_base的內置class對象,Python將爲其指定一個默認的基類:PyBaseObject_Type
就是特殊的<type 'object'>
Python所有class對象都是直接或間接以<type 'object'>作爲基類的。
PyType_Type沒有指定基類,它的基類爲<type 'object'>

判斷基類是否已經被初始化完成的調試是base->tp_dict是否爲NULL,初始化的一部分工作就是對tp_dict進行填充

2.2 處理基類列表
Python支持多重繼承,每一個Python的class對象都會有一個基類列表

slot這一部分沒有弄明白

MRO
Python虛擬機對Python的內置類型對應的PyTypeObject進行了多種複雜的改造工作:
a.設置type信息、基類及基類列表
b.填充tp_dict
c.確定mro列表
d.基於mro列表從基類繼承操作
e.設置基類的子類列表

3.用戶自定義class
類的成員函數和一般的函數相同,同樣會有這種聲明和實現分離的現象

創建class對象和創建instance對象的不同之處正是在於tp_new不同。創建class對象,Python虛擬機使用的是type_new
而對於instance對象,Python虛擬機則使用object_new

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章