latest Python Doc仅对PyModule_Create
:
模块初始化函数可以直接创建和返回模块对象。这称为“单相初始化”,并使用以下两个模块创建函数之一:
PyObject* PyModule_Create(PyModuleDef *def)
- 根据 def 中的定义创建一个新模块对象。其行为类似于
PyModule_Create2()
,其中 module_api_version 设置为PYTHON_API_VERSION
。- ...
在初始化函数返回之前,生成的模块对象通常使用
PyModule_AddObject()
等函数填充。
此外,PyModule_Create
不在this question的列表中。这表明正在遵循传统行为,即调用者应该“获得”对返回的PyObject*
的引用。
但是,从这篇python3porting博文中,它有以下示例:
static PyObject *
moduleinit(void)
{
MOD_DEF(m, "themodulename",
"This is the module docstring",
module_methods)
if (m == NULL)
return NULL;
if (PyModule_AddObject(m, "hookable",
(PyObject *)&hookabletype) < 0)
return NULL; /* line A */
return m;
}
'A行'是否会泄漏此代码路径的引用? PyModule_Create
的正确用法和所有权语义是什么?
答案 0 :(得分:4)
该代码段不能正确管理引用计数。除了你发现的泄漏之外,它还会忘记Py_INCREF(&hookabletype)
,尽管事实是PyModule_AddObject
steals a reference to the value。
通常在没有另行规定的情况下,PyModule_Create
会返回一个新的引用,而不是借来的引用。