讀python源碼--對象模型

  學python的人都知道,python中一切皆是對象,如class生成的對象是對象,class自己也是對象,int是對象,str是對象,dict是對象...。因此,我很好奇,python是怎樣實現這些對象的?帶着這份好奇,我決定去看看python的源碼,畢竟源碼纔是知足本身好奇心最直接的方法。python

 

  在object.h文件中,定義了兩種數據結構PyObject和PyVarObject,代碼以下:數據結構

 1 #define PyObject_HEAD                \
 2     Py_ssize_t ob_refcnt;               \
 3     struct _typeobject *ob_type;
 4 
 5 #define PyObject_VAR_HEAD       \
 6     PyObject_HEAD                       \
 7     Py_ssize_t ob_size;
 8 
 9 typedef struct _object {
10     PyObject_HEAD
11 } PyObject;
12 
13 typedef struct {
14     PyObject_VAR_HEAD
15 } PyVarObject;

  這兩種數據結構分別對應python的兩種對象:固定長度對象和可變長度對象。python中的全部對象都屬於這兩種對象中的一種,如int,float是固定長度對象,list,str,dict是可變長度對象。從上面兩種對象數據結構定義來看,可變長度對象和固定長度對象的頭都是PyObject結構體,也就是說python中全部對象的開頭都包含這個結構體,而且能夠用PyObject *指針來訪問任何對象,這種訪問對象的方法在python的源碼中隨處可見。PyObject結構體包含兩個成員,ob_refcnt和ob_type指針。ob_refcnt用來表示對象被引用的次數,當ob_refcnt == 0時,這個對象會被當即銷燬;ob_type指針指向了一個_typeobject類型的結構體,表示對象所屬的類型,也就是生成該對象的類型,這其實很相似於面向對象中類與實例的關係,PyObject是某個類的實例,ob_type表示這個類。但與面向對象不一樣的是,ob_type自己也是個對象,咱們來看下_typeobject的定義:app

 1 typedef struct _typeobject {
 2     PyObject_VAR_HEAD
 3     const char *tp_name; /*類型名 */
 4     Py_ssize_t tp_basicsize, tp_itemsize; /* 實例化對象的大小 */
 5 
 6     /* 標準方法 */
 7 
 8     destructor tp_dealloc;
 9     printfunc tp_print;
10     getattrfunc tp_getattr;
11     setattrfunc tp_setattr;
12     cmpfunc tp_compare;
13     reprfunc tp_repr;
14 
15     /* 標準類(數值類,列表類,dict類)方法*/
16 
17     PyNumberMethods *tp_as_number;
18     PySequenceMethods *tp_as_sequence;
19     PyMappingMethods *tp_as_mapping;
20 
21     /* 其它標準方法*/
22 
23     hashfunc tp_hash;
24     ternaryfunc tp_call;
25     reprfunc tp_str;
26     getattrofunc tp_getattro;
27     setattrofunc tp_setattro;
28     ...   
29 } PyTypeObject;

  從上面定義來看,_typeobject的開頭也包含了PyObject結構體,因此它也是一個對象,既然它也是一個對象,那麼按照面向對象的理解,它又是誰來生成的呢?答案是全部PyTypeObject對象都是經過PyType_Type來生成的,包括PyType_Type自己,由於PyType_Type也是PyTypeObject對象,有點繞。PyType_Type的定義是經過將PyType_Type聲明爲全局靜態變量實現的,具體以下:spa

 1 PyTypeObject PyType_Type = {
 2     PyVarObject_HEAD_INIT(&PyType_Type, 0)
 3     "type",                                     /* tp_name */
 4     sizeof(PyHeapTypeObject),                   /* tp_basicsize */
 5     sizeof(PyMemberDef),                        /* tp_itemsize */
 6     (destructor)type_dealloc,                   /* tp_dealloc */
 7     0,                                          /* tp_print */
 8     0,                                          /* tp_getattr */
 9     0,                                          /* tp_setattr */
10     0,                                  /* tp_compare */
11     (reprfunc)type_repr,                        /* tp_repr */
12     0,                                          /* tp_as_number */
13     0,                                          /* tp_as_sequence */
14     0,                                          /* tp_as_mapping */
15     (hashfunc)_Py_HashPointer,                  /* tp_hash */
16     (ternaryfunc)type_call,                     /* tp_call */
17     0,                                          /* tp_str */
18     (getattrofunc)type_getattro,                /* tp_getattro */
19     (setattrofunc)type_setattro,                /* tp_setattro */
20     0,                                          /* tp_as_buffer */
21     ...
22 }

  從PyType_Type定義來看,ob_type被初始化爲它本身的地址,因此PyType_Type的類型就是本身。從python源碼實現來看,全部PyTypeObject的ob_type都會指向PyType_Type對象,因此PyType_Type是全部類型的類型,稱之爲元類。python中定義了不少內建的類型對象,如PyInt_Type (int類型),PyStr_Type (str類型),PyDict_Type(dict類型) 類型對象,下面看下PyInt_Type類型的定義:指針

 1 PyTypeObject PyInt_Type = {
 2     PyVarObject_HEAD_INIT(&PyType_Type, 0)
 3     "int",
 4     sizeof(PyIntObject),
 5     0,
 6     (destructor)int_dealloc,                    /* tp_dealloc */
 7     (printfunc)int_print,                       /* tp_print */
 8     0,                                          /* tp_getattr */
 9     0,                                          /* tp_setattr */
10     (cmpfunc)int_compare,                       /* tp_compare */
11     (reprfunc)int_to_decimal_string,            /* tp_repr */
12     &int_as_number,                             /* tp_as_number */
13     0,                                          /* tp_as_sequence */
14     0,                                          /* tp_as_mapping */
15     (hashfunc)int_hash,                         /* tp_hash */
16     0,                                          /* tp_call */
17     ...
18 };

  從PyInt_Type定義來看,它主要包含了int數據類型相關的方法。PyInt_Type 類型對象的初始化和PyType_Type 類型相似,PyInt_Type類型的定義也是經過全局靜態變量的方式實現的,除了PyInt_Type了下,全部python內建類型都是以這種方式定義的。這些類型產生的對象都會共享這些類型對象,包括這些類型定義的方法。code

  在python中,怎樣查看對象的類型呢?有兩種方法,一種是直接type:對象

1 >>> x = 1
2 >>> type(x)
3 <type 'int'>

  另外一種是經過對象的__class__屬性:blog

1 >>> x = 1
2 >>> type(x)
3 <type 'int'>
4 >>> x.__class__
5 <type 'int'>

  如今來看看int,str,dict這些類型的類型:ci

1 <type 'int'>
2 >>> type(int)
3 <type 'type'>
4 >>> type(str)
5 <type 'type'>
6 >>> type(dict)
7 <type 'type'>
8 >>> type(type)
9 <type 'type'>

  從這個輸出來看,int,str,dict這些類型的類型都是type,這也印證了前面說的,全部類型都是經過元類type生成的。get

相關文章
相關標籤/搜索