在Python扩展中解压缩迭代

时间:2016-08-07 10:04:30

标签: python-c-api

我正在尝试将a, b, c, d = iterable翻译为Python的C / API。

我正在寻找类似于PyArg_ParseTuple的函数,仅用于迭代。

换句话说,PyIter_ParsePyObject_ParseIterable区域内的内容,如果此类函数存在的话。

有关如何实施它的任何提示?

1 个答案:

答案 0 :(得分:2)

不,没有辅助功能可以为你做这件事。

您必须使用PyIter_Next()最多max次来检索值,在您无法获得至少min值时引发异常,然后只需从中构建一个元组。

类似(未经测试,主要是从PySequence_Tuple()窃取):

int
PyIter_LimitedTuple(PyObject *v, Py_ssize_t min, Py_ssize_t max)
{
    PyObject *it;  /* iter(v) */
    PyObject *result = NULL;
    Py_ssize_t j;

    it = PyObject_GetIter(v);
    if (it == NULL)
        return NULL;

    /* allocate space. */
    result = PyTuple_New(max);
    if (result == NULL)
        goto Fail;

    /* Fill the tuple. */
    for (j = 0; ; ++j) {
        PyObject *item = PyIter_Next(it);
        if (item == NULL) {
            if (PyErr_Occurred())
                goto Fail;
            break;
        }

        if (j > max) {
            PyErr_Format(PyExc_ValueError,
                "too many values to unpack");
            goto Fail;
        }

        PyTuple_SET_ITEM(result, j, item);
    }

    if (j < min) {
        PyErr_Format(PyExc_ValueError,
            "need more than %d value to unpack",
            j);
        goto Fail;
    }

    /* Cut tuple back if fewer than max items were available. */
    if (j < max &&
        _PyTuple_Resize(&result, j) != 0)
        goto Fail;

    Py_DECREF(it);
    return result; 

Fail:
    Py_XDECREF(result);
    Py_DECREF(it);
    return NULL;
}

然后将生成的元组传递给PyArg_UnpackTuple()