Python C扩展:如何对PyArrayObjects的C数组进行DECREF

时间:2018-12-28 00:50:37

标签: python c python-3.x numpy python-c-api

我正在为python创建一些C扩展代码(下面的示例)。 该函数的一部分要求我迭代作为参数传入的数组,对每个元素进行计算,然后返回计算值的数组。

我正在使用NpyIter_MultiNew,因为它可以遍历多个数组,还可以为输出创建合适的数组。

NpyIter_MultiNew需要一个PyArrayObject *的C数组作为输入(此处为op)。 opPyArray_FROM_OTF的输出填充。 这些是新参考,因此我需要在代码末尾进行清理。

问题,我有什么需要对DECREF进行解码? (即<>中应该包含的内容

选项1:

Py_XDECREF(op);

选项2:

Py_XDECREF(op[0]);
Py_XDECREF(op[1]);
Py_XDECREF(op[2]);

选项3:

Py_XDECREF(op[0]);
Py_XDECREF(op[1]);
Py_XDECREF(op[2]);
Py_XDECREF(op);

我认为Py_XDECREF(op[0])也可能是不必要的。 我怀疑op[0]仍为NULL,只是用作NpyIter_MultiNew的标志以指示新数组的创建。 新的输出数组从output = NpyIter_GetOperandArray(iter)[0];

恢复

注意: PyObject * args_in[2]中使用的引用是借用的,因此不需要INCREFDECREF

static PyObject *
UseArray(PyObject * args){

    PyObject * args_in[2];

    PyArrayObject * op[3] = {NULL, NULL, NULL};
    npy_uint32 op_flags[3];

    PyArrayObject * output = NULL;

    // python inputs
    if (!PyArg_ParseTuple(args, "OO", &args_in[0], &args_in[1])){
        goto fail;
    }

    // output array
    op[0] = NULL;
    op_flags[0] = NPY_ITER_WRITEONLY | NPY_ITER_ALLOCATE;

    // input array
    op[1] = (PyArrayObject *) PyArray_FROM_OTF(args_in[0], NPY_DOUBLE, NPY_ARRAY_IN_ARRAY);
    op_flags[1] = NPY_ITER_READONLY;
    if (op[1] == NULL){
        goto fail;
    }
    op[2] = (PyArrayObject *) PyArray_FROM_OTF(args_in[1], NPY_DOUBLE, NPY_ARRAY_IN_ARRAY);
    op_flags[2] = NPY_ITER_READONLY;
    if (op[2] == NULL){
        goto fail;
    }

    // iterate
    iter = NpyIter_MultiNew(3, op, NPY_ITER_EXTERNAL_LOOP, NPY_KEEPORDER, NPY_NO_CASTING, op_flags, NULL);
    <<iterator code>>

    // get output array
    output = NpyIter_GetOperandArray(iter)[0];
    Py_INCREF(output);

    if (NpyIter_Deallocate(iter) != NPY_SUCCEED){
        goto fail;
    }

    <<DECREF op>>

    return PyArray_Return(output);

    fail:
        <<DECREF op>>
        Py_XDECREF(output);
        return NULL;
}

0 个答案:

没有答案