Python进阶编程:编写更高效、优雅的Python代码
上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 对象运行