在 Python 扩展中解压可迭代对象
Unpacking iterable in Python extension
我正在尝试将 a, b, c, d = iterable
翻译成 Python 的 C/API。
我正在寻找类似于 PyArg_ParseTuple
的函数,仅用于迭代。
换句话说,在 PyIter_Parse
或 PyObject_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()
。
我正在尝试将 a, b, c, d = iterable
翻译成 Python 的 C/API。
我正在寻找类似于 PyArg_ParseTuple
的函数,仅用于迭代。
换句话说,在 PyIter_Parse
或 PyObject_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()
。