从C返回对象到Python

Cha*_*l72 8 c python python-c-api python-c-extension

我已经阅读了Python C-API的文档,甚至还编写了一些扩展模块.但是,在从C函数返回Python对象时,我仍然有点不清楚它的确切语义.

Python文档中的有限示例通常显示一个返回结果的C函数Py_BuildValue.现在,Py_BuildValue返回a New Reference,并将此引用的所有权转移给解释器.那么,我可以从中推断出一般规则是返回Python的任何对象必须是新引用,并且从C函数返回对象与将对象的所有权转移到解释器相同吗?

如果是这样,那么返回已经拥有某个东西的对象的情况又如何呢?例如,假设你编写一个C函数,它接受a PyObject*是a tuple,然后调用PyTuple_GetItem它并返回结果. PyTuple_GetItem返回一个借来的引用 - 意味着该项仍然由元组"拥有".那么,在将函数返回给解释器之前,返回结果的C函数PyTuple_GetItem是否有INCREF结果?

例如:

static PyObject* my_extension_module(PyObject* tup)
{
   PyObject* item = PyTuple_GetItem(tup, 1);
   if (!item) { /* handle error */ }

   return item; // <--- DO WE NEED TO INCREF BEFORE RETURNING HERE?
}
Run Code Online (Sandbox Code Playgroud)

Tho*_*ers 5

Python期望你向它公开的任何函数都返回一个新的引用,是的.如果您只有借来的参考,您必须打电话Py_INCREF给一个新的参考.如果你返回一个借用的引用,Python将继续调用Py_DECREF(当它完成引用时),并最终导致该对象在它仍在使用时被释放.

(在解释器退出期间发生"最终"释放的情况并不罕见,在这种情况下它可能会被忽视,但返回借用的引用仍然是错误的.)