3

我正在开发一个接口,以便 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 文档,“对于静态分配的类型对象,tp_name 字段应该包含一个点。”;出于这个原因,我tp_name"abc.MyType". 当我这样做时,在加载模块后,'module' object has no attribute 'MyType'当我尝试使用该类型时(例如x = abc.MyType(),以前做过import abc)。如果我使用 just "MyType",它似乎可以工作,但这似乎与官方文档和教程中的示例相矛盾。

那么该tp_name字段的确切含义是什么,它应该真正包含什么?我不把模块名放进去有什么影响?

4

1 回答 1

5

通过做

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

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

于 2011-07-06T10:02:30.760 回答