从C返回对象到Python

时间:2011-05-30 13:06:42

标签: python c python-c-api python-c-extension

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

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

如果是这样,那么返回已经拥有某个东西的对象的情况呢?例如,假设您编写了一个C函数,该函数接收PyObject* tuple,并在其上调用PyTuple_GetItem并返回结果。 PyTuple_GetItem返回借用的引用 - 意味着该项仍然由元组“拥有”。那么,在将结果返回给解释器之前,返回类似PyTuple_GetItem之类结果的C函数是否必须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?
}

1 个答案:

答案 0 :(得分:5)

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

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