我正在用 C 编写 Python 扩展。我的函数将 Numpy 数组列表(包含整数)作为参数。我遍历列表,获取每个数组,增加引用,获取指向数组的 C 指针,然后减少引用。
if (!PyArg_ParseTuple(args, "O", &list))
return NULL;
long nb_arrays = PyList_Size(list);
arrays = (int **) malloc(nb_arrays * sizeof(int *));
for (i = 0; i < nb_arrays; i++)
{
PyArrayObject *array = (PyArrayObject *) PyList_GetItem(list, i);
Py_INCREF(array);
arrays[i] = (int *) PyArray_DATA(array);
Py_DECREF(array);
}
在此循环之后,我使用指针进行计算。它是正确的还是我必须等待函数结束才能减少引用计数?
最佳答案
PyArray_DATA
对其应用的数组的引用计数没有影响。此外,当创建传递给您的函数的列表时,其中每个数组的引用计数都会增加 1。因此,虽然它们不会造成太大伤害,但那些 Py_INCREF
和 Py_DECREF
是完全不必要的,您可以摆脱它们。
当您要将对象传递给窃取引用的函数时,您通常必须 Py_INCREF
一个对象(即取得它的所有权并承担在完成时减少计数的责任需要它)。
您通常必须 Py_DECREF
您在函数内创建的任何临时对象,这些对象不是您的返回的一部分,并且任何返回都不需要它们。
你很少(如果有的话)必须先 Py_INCREF
一些东西,然后再 Py_DECREF
它。您可能会编写一些乱七八糟的多线程代码来释放 GIL,从而使该段落不正确,但通常传递给您的函数的所有内容都是元组(如果是位置参数)或字典(如果是关键字参数)的一部分,因此在调用时它的引用计数增加了。在您的函数返回之前,该元组和字典不会被销毁,因此可以安全地假设传递给您的所有项目都不会在您的函数中途被垃圾收集,即您正在借用该引用,因此无需显式增加引用计数只是为了访问对象。
关于python - 调用 PyArray_DATA 后 DECREF'ing,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37919094/