我想创建一个 C 函数,它返回元组列表、字典列表,甚至更好,返回我在另一个 python 模块中定义的类的对象列表。
C API(《Python/C API》)的文档提到,要构建一个复杂的对象,我需要调用使用可变数量参数的 Py_BuildValue
或 Py_VaBuildValue
使用 va_list
参数。
由于 C 无法使用可变数量的参数动态进行调用,因此我无法使用 Py_BuildValue
并且必须使用 Py_VaBuildValue
,但正在寻找如何构建 va_list
变量,我发现 There's no ability to fill a va_list explicitly 的回复和 tells me to make it from a variable parameters function ,这违背了目的……从所做的测试来看,我得到的只是段错误和核心转储。
那么,我应该如何使用这些功能?
最佳答案
您不应该使用这些函数来构建动态大小的数据结构。 FAQ说对于任意大小的元组使用 PyTuple_Pack 而不是 Py_BuildValue,但这也是错误的;我不知道为什么这么说。 PyTuple_Pack 与 Py_BuildValue 具有相同的可变参数问题。
要从 C 构建可变长度元组,请使用 PyTuple_New
构造所需长度的未初始化元组,然后循环索引并使用 PyTuple_SET_ITEM
设置元素。是的,这会改变元组。 PyTuple_SET_ITEM
仅可以安全地用于初始化尚未暴露给其他代码的新元组。另外,请注意 PyTuple_SET_ITEM
窃取对新元素的引用。
例如,构建一个 0 到 n-1 之间的整数元组:
PyObject *tup = PyTuple_New(n);
for (int i = 0; i < n; i++) {
// Note that PyTuple_SET_ITEM steals the reference we get from PyLong_FromLong.
PyTuple_SET_ITEM(tup, i, PyLong_FromLong(i));
}
要从 C 语言构建可变长度列表,您可以使用 PyList_New
和 PyList_SET_ITEM
执行相同的操作,也可以使用 PyList_New 构建空列表(0)
并使用 PyList_Append
附加项目,就像您在 Python 中使用 []
和 append
(如果您没有这样做)一样具有列表理解或序列乘法。
关于python - 当用C扩展Python时,如何用C动态构建复杂的结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55987022/