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