Если вы получаете заемную ссылку, но НЕ возвращаете ее на Python землю, следует ли вам делать Py_INCREF
, когда вы ее получите, и затем Py_DECREF
, когда вы закончите с ней, или это излишне?
Например, этот тривиальный пример получает заимствованную ссылку из PyDict_GetItem
, делает некоторые вещи с заимствованной ссылкой, а затем возвращает None
в Python землю. Есть ли необходимость в Py_INCREF
/ Py_DECREF
заимствованной ссылке при работе с ней здесь?
static PyObject PyFoo_bar(PyFoo *self, int field)
{
int field = 0;
PyFoo *child = NULL;
if (!PyArg_ParseTuple(args, "i", &field) {
return NULL;
}
child = PyDict_GetItem(self->children, field);
// Long code omitted that works on child
// Is it safe to do so without a Py_INCREF on child now followed by PY_DECREF later?
// NOT returning child here - just return None
Py_RETURN_NONE;
}
Меня беспокоит то, что после вызова PyDict_GetItem
счетчик ссылок child
может каким-то образом упасть до нуля, а затем освободить, пока я работаю с ним. Это вообще возможно? Я так не думаю, так как GIL здесь не опущен, но я не уверен.
С другой стороны, мне интересно, будет ли это просто наилучшей практикой делать Py_INCREF
/ Py_DECREF
Вот. Возможно, позже я оставлю GIL, или позже решу вернуть ребенка. Py_INCREF
дешево. Например, было бы лучше сделать это так:
child = PyDict_GetItem(self->children, field);
Py_INCREF(child);
// Long code omitted
Py_DECREF(child);
Py_RETURN_NONE;