这个问题很简单,但有助于加深我的理解。我知道 C 扩展函数的参数在 C 代码期间保证是实时引用(除非手动 DECREFed)。但是,如果我有一个 C 扩展代码返回一个存在于它的参数列表中的 PyObject*,我是否需要在返回它之前 INCREF 参数?即,以下两项中哪一项是正确的:
static PyObject return_item(PyObject *self, PyObject *item)
{
// manipulate item
return item;
}
或
static PyObject return_item(PyObject *self, PyObject *item)
{
// manipulate item
Py_INCREF(item);
return item;
}
基于 https://docs.python.org/3/extending/extending.html#ownership-rules ,它说
The object reference returned from a C function that is called from Python must be an owned reference — ownership is transferred from the function to its caller.
和Returning objects to Python from C我假设是后者(INCREFing 是要走的路)但我想确定。
最佳答案
如果有人从 Python 调用 return_item
函数,他们可能会这样做:
something = Something()
something_else = return_item(something)
del something
如果 return_item
没有返回传入的参数,而是返回其他东西,你会期望此时传入的 something
应该被释放内存,因为它的引用计数降为零。
如果你不 Py_INCREF
并返回同一个对象,那仍然会发生 - 对象的引用计数将下降到 0,你将在 something_else
中有一个无效对象>.
TL;DR:是的,您应该 Py_INCREF
,因为您通过从函数返回该对象创建了另一个引用。
关于python - 从 Python C 扩展函数返回参数时需要 INCREF?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57661466/