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

Jam*_*nze 3 python

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

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

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

\n

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

\n

Tho*_*ers 5

通过做

PyModule_AddObject(module, type->tp_name, as<PyObject>(type));
Run Code Online (Sandbox Code Playgroud)

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