學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