首先看一个例子:
1 >>> a = 1 2 >>> a 3 1 4 >>> type(a) 5 <type 'int'> 6 >>> type(type(a)) 7 <type 'type'> 8 >>> type(int) 9 <type 'type'> 10 >>> type(type(type(a))) 11 <type 'type'> 12 >>> type(type(int)) 13 <type 'type'>
我们反向推导一个int
对象是怎么生成的。
1. 定义一种类型叫PyTypeObject
代码位置 Include/object.h
1 typedef struct _typeobject { 2 3 /* MARK: base, 注意, 是个变长对象*/ 4 PyObject_VAR_HEAD 5 const char *tp_name; /* For printing, in format "." */ //类型名 6 Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */ // 创建该类型对象时分配的内存空间大小 7 8 // 一堆方法定义, 函数和指针 9 /* Methods to implement standard operations */ 10 printfunc tp_print; 11 hashfunc tp_hash; 12 13 /* Method suites for standard classes */ 14 PyNumberMethods *tp_as_number; // 数值对象操作 15 PySequenceMethods *tp_as_sequence; // 序列对象操作 16 PyMappingMethods *tp_as_mapping; // 字典对象操作 17 18 // 一堆属性定义 19 .... 20 21 } PyTypeObject;
说明:
1 1. tp_name 2 类型名, 这里是"type" 3 4 2. PyVarObject_HEAD_INIT(&PyType_Type, 0) 5 PyVarObject_HEAD_INIT, 这个方法在 Include/object.h中, 6 等价于 7 ob_refcnt = 1 8 *ob_type = &PyType_Type 9 ob_size = 0 10 11 即, PyType_Type的类型是其本身!1. tp_name 12 类型名, 这里是"type" 13 14 2. PyVarObject_HEAD_INIT(&PyType_Type, 0) 15 PyVarObject_HEAD_INIT, 这个方法在 Include/object.h中, 16 等价于 17 ob_refcnt = 1 18 *ob_type = &PyType_Type 19 ob_size = 0 20 21 即, PyType_Type的类型是其本身!
所有Type都是PyTypeObject的”实例”: PyType_Type/PyInt_Type。
2. 然后, 用PyTypeObject初始化得到一个对象PyType_Type
代码位置 Objects/typeobject.c
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 8 // type对象的方法和属性初始化值 9 ..... 10 11 };
说明:
1 1. tp_name 2 类型名, 这里是"type" 3 4 2. PyVarObject_HEAD_INIT(&PyType_Type, 0) 5 PyVarObject_HEAD_INIT, 这个方法在 Include/object.h中, 6 等价于 7 ob_refcnt = 1 8 *ob_type = &PyType_Type 9 ob_size = 0 10 11 即, PyType_Type的类型是其本身!1. tp_name 12 类型名, 这里是"type" 13 14 2. PyVarObject_HEAD_INIT(&PyType_Type, 0) 15 PyVarObject_HEAD_INIT, 这个方法在 Include/object.h中, 16 等价于 17 ob_refcnt = 1 18 *ob_type = &PyType_Type 19 ob_size = 0 20 21 即, PyType_Type的类型是其本身!1. tp_name 22 类型名, 这里是"type" 23 24 2. PyVarObject_HEAD_INIT(&PyType_Type, 0) 25 PyVarObject_HEAD_INIT, 这个方法在 Include/object.h中, 26 等价于 27 ob_refcnt = 1 28 *ob_type = &PyType_Type 29 ob_size = 0 30 31 即, PyType_Type的类型是其本身!
结构
第一张图, 箭头表示实例化
(google doc用不是很熟找不到对应类型的箭头)
第二张图, 箭表示指向
1 # 1. int 的 类型 是`type` 2 >>> type(int) 3 4 # 2. type 的类型 还是`type`, 对应上面说明第二点 5 >>> type(type(int))
注意: 无论任何时候, ob_type指向的是 PyTypeObject的实例: PyType_Type/PyInt_Type…
3. 再然后, 定义具体的类型, 这里以PyInt_Type为例子
代码位置 Objects/intobject.c
PyTypeObject PyInt_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "int", sizeof(PyIntObject), 0, // int类型的相关方法和属性值 .... (hashfunc)int_hash, /* tp_hash */ }; 说明: 1. "int" PyInt_Type的类型名是int 2.PyVarObject_HEAD_INIT(&PyType_Type, 0) PyInt_Type的*ob_type = &PyType_Type
其结构图为:
即就是python的如下代码:
1 >>> type(1) 2 <type 'int'> 3 4 >>> type(type(1)) 5 <type 'type'>
4. 最后, 生成一个整数对象int
代码位置 Include/intobject.h
1 typedef struct { 2 PyObject_HEAD 3 long ob_ival; 4 } PyIntObject; 5 说明: 6 1. PyIntObject为整数类型,声明一个整数后得到整数对象, 对象ob_type指向PyInt_type对象
5.到这里, 总结下
1. 一切都是对象
2. PyType_Type / PyInt_Type / PyString_Type ....等,这些是`类型对象`, 可以认为是同级, 都是PyTypeObject这种`类型`的实例!
3. 虽然是同级,但是其他PyXXX_Type, 其类型指向 PyType_Type,PyType_Type 的类型指向自己, 它是所有类型的`类型`
4. PyTypeObject 是一个变长对象
5. 每个object, 例如PyIntObject都属于一种`类型`,object初始化时进行关联。
6. 多态是如何实现的?
对象的多态, 例如hash:
1 >>> hash(1) 2 1 3 >>> hash("abc") 4 1453079729188098211
从上面数据结构可以看到, 方法及属性, 在不同Type实例化时就确定了:
1 PyTypeObject PyInt_Type = { 2 ... 3 (hashfunc)int_hash, /* tp_hash */ 4 ... 5 } 6 7 PyTypeObject PyString_Type = { 8 ... 9 (hashfunc)string_hash, /* tp_hash */ 10 ... 11 }
Python内部传递的是泛型指针PyObject *
, 函数调用时, 找到其类型* ob_type
, 然后调用,即:
object -> ob_type -> tp_hash