Python进阶编程:编写更高效、优雅的Python代码
上QQ阅读APP看书,第一时间看更新

0.3.9 对象的多态性

Python在创建一个对象比如PyLongObject时,会分配内存进行初始化。然后,Python内部会用PyObject*变量来维护这个对象,其他对象与此类似,所以在Python内部各个函数之间传递的都是范型指针——PyObject*。如果你不清楚这个指针所指的对象是什么类型,只能通过所指对象的ob_type域动态进行判断,而Python正是通过ob_type实现了多态机制。

以calc_hash函数为例,相关源码如下:


Py_hash_t
calc_hash(PyObject* object)
{
    Py_hash_t hash = object->ob_type->tp_hash(object);
    return hash;
}

如果传递给calc_hash函数的指针是PyLongObject*,那么它会调用PyLongObject对象对应的类型对象中定义的hash操作tp_hash。tp_hash可以在PyTypeObject中找到,而具体赋值绑定可以在PyLong_Type初始化源码中看到,其绑定的是long_hash函数:


// Objects/longobject.c
PyTypeObject PyLong_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "int",                                      /* tp_name */
    ...

    (hashfunc)long_hash,                        /* tp_hash */

    ...
};

如果指针是PyUnicodeObject*,就会调用PyUnicodeObject对象对应的类型对象中定义的hash操作。查看源码,我们可以看到实际绑定的是unicode_hash函数:


// Objects/unicodeobject.c
PyTypeObject PyUnicode_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "str",              /* tp_name */
    ...
    (hashfunc) unicode_hash,        /* tp_hash*/
    ...
};