上QQ阅读APP看书,第一时间看更新
0.3.6 类型的类型
PyTypeObject对象定义中,第一行是宏PyObject_VAR_HEAD。查看源码可知PyType-Object是一个变长对象,相关源码(Include/object.h)如下:
// Include/object.h #define PyObject_VAR_HEAD PyVarObject ob_base;
对象的类型是由该对象指向的类型对象决定的,那么类型对象的类型是由谁决定呢?我们可以通过与其关联的类型对象确定类型。那么,如何来确定一个对象是类型对象呢?答案就是PyType_Type。
PyType_Type相关源码(Objects/typeobject.c)如下:
// Objects/typeobject.c PyTypeObject PyType_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "type", /* tp_name */ sizeof(PyHeapTypeObject), /* tp_basicsize */ sizeof(PyMemberDef), /* tp_itemsize */ ...... };
PyType_Type在类型机制中至关重要,所有用户自定义class所对应的PyTypeObject对象都是通过PyType_Type创建的。
现在看看PyLong_Type是怎么与PyType_Type建立联系的。前面提到在Python中,每一个对象都将自己的引用计数、类型信息保存在开始的部分。为了方便对这部分内存初始化,Python中提供了有用的宏。相关源码(Include/object.h)如下:
// Include/object.h #ifdef Py_TRACE_REFS #define _PyObject_EXTRA_INIT 0, 0, #else #define _PyObject_EXTRA_INIT #endif #define PyObject_HEAD_INIT(type) \ { _PyObject_EXTRA_INIT \ 1, type },
这些宏在各种内置类型对象的初始化中被大量使用。以PyLong_Type为例,我们可以清晰地看到一般的类型对象和PyType_Type之间的关系。
相关源码(Objects/longobject.c)片段如下:
// Objects/longobject.c PyTypeObject PyLong_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "int", /* tp_name */ offsetof(PyLongObject, ob_digit), /* tp_basicsize */ sizeof(digit), /* tp_itemsize */ ...... };
对象运行如图0-5所示。
图0-5 对象运行