读python源码--对象模型
学python的人都知道,python中一切皆是对象,如class生成的对象是对象,class本身也是对象,int是对象,str是对象,dict是对象...。所以,我很好奇,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的定义:
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声明为全局静态变量实现的,具体如下:
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内建类型都是以这种方式定义的。这些类型产生的对象都会共享这些类型对象,包括这些类型定义的方法。
在python中,怎样查看对象的类型呢?有两种方法,一种是直接type:
1 >>> x = 1 2 >>> type(x) 3 <type 'int'>
另一种是通过对象的__class__属性:
1 >>> x = 1 2 >>> type(x) 3 <type 'int'> 4 >>> x.__class__ 5 <type 'int'>
现在来看看int,str,dict这些类型的类型:
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生成的。