在 Python 扩展中解压可迭代对象

Unpacking iterable in Python extension

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

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

换句话说,在 PyIter_ParsePyObject_ParseIterable 范围内的东西,如果这些功能已经存在的话。

有什么实施技巧吗?

不,没有可以为您执行此操作的辅助函数。

你必须使用 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()