在Python扩展中定义类型时,我应该在tp_name字段中添加什么?

时间:2011-07-06 09:55:19

标签: python

我正在开发一个接口,以便Python程序可以调用现有的C ++库。如果我理解正确,那么这个接口(和C ++库)应该作为模块导入,比如abc。接口中的类型在接口的C ++端定义为静态变量,并使用以下序列在Python中注册:

void PythonRegistrationData::RegisterType(PyObject* module, PyTypeObject* type)
{
    if (type->ob_refcnt < 2)
    {
        if (type->tp_base != NULL)
            RegisterType(module, type->tp_base);
        Py_INCREF(type);
        if (PyType_Ready(type) != 0)
            throw GPython::DummyError();
        PyModule_AddObject(module, type->tp_name, as<PyObject>(type));
    }
}

(递归是为了确保在派生类之前注册基类。模块已经创建过了。)根据C-API docs,“对于静态分配的类型对象,tp_name字段应该包含一个点。”;因此,我使用tp_name初始化"abc.MyType"。当我这样做时,在加载模块后,当我尝试使用该类型时(例如'module' object has no attribute 'MyType',之前已经完成x = abc.MyType()),我得到import abc。如果我只使用"MyType",它似乎有效,但这似乎与官方文档和教程中的示例相矛盾。

那么tp_name字段的确切含义是什么,它应该包含什么?我没有把模块名称放在里面的效果是什么?

1 个答案:

答案 0 :(得分:4)

通过

PyModule_AddObject(module, type->tp_name, as<PyObject>(type));

您正在使用“abc.MyType”作为属性名称将类型添加到模块(这意味着设置属性)。这意味着如果您想在getattr(abc, 'abc.MyType')模块上访问它,则需要使用abc访问它(您无法直接访问名称中包含点的属性。)应该tp_name设置为“限定”名称(前面有abc.),您不应该使用tp_name作为属性名称。