python - 当用C扩展Python时,如何用C动态构建复杂的结构?

标签 python c python-3.x variadic-functions

我想创建一个 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_NewPyList_SET_ITEM 执行相同的操作,也可以使用 PyList_New 构建空列表(0) 并使用 PyList_Append 附加项目,就像您在 Python 中使用 []append(如果您没有这样做)一样具有列表理解或序列乘法。

关于python - 当用C扩展Python时,如何用C动态构建复杂的结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55987022/

相关文章:

python - 升级: 'module' object has no attribute 'SSL_ST_INIT' 后pip出错

C 程序无法识别头文件中的常量

c - 内核 - Linux - 内核在哪里与 cpu 对话?

c - 未知的错误字符被添加到字符串中?

python - OpenCV 无法正确写入输出文件 (Python)

python - 确定工作线程是否正在执行任何工作

python - 我应该如何处理在我的 setup.py 脚本中导入第三方库?

python - Snakemake如何忽略RuntimeWarning?

python - FTP 库错误 : got more than 8192 bytes

python - 如何在 Anaconda 环境中更改 Python 解释器路径?