Я прочитал документацию по Python C-API и даже написал несколько модулей расширения. Однако мне все еще не совсем ясна точная семантика, когда дело доходит до возврата объектов Python из функции C.
Ограниченные примеры в документации Python обычно показывают функцию C, которая возвращает результат Py_BuildValue
. Теперь Py_BuildValue
возвращает новую ссылку
и передает право владения этой ссылкой интерпретатору. Итак, могу ли я экстраполировать из этого, что это общее правило, что любой объект, возвращаемый Python, должен быть новой ссылкой , и что возвращение объекта из функции C - это то же самое, что передача права собственности на объект интерпретатору?
Если да, то как насчет случаев, когда вы возвращаете объект, который уже кому-то принадлежит? Например, предположим, что вы пишете функцию C, которая принимает PyObject *
, который является кортежем
, и вы вызываете для нее 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?
}