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

1.Python中的對象模型
python中全部東西都是對象python

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

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

<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判斷兩個對象間是否存在何種關係code

複製代碼
>>> 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'>blog

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

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

slot這一部分沒有弄明白it

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

相關文章
相關標籤/搜索