使用 C 扩展 Python 时,如何在 C 中动态构建复杂结构? [英] When extending Python with C, How do one dynamically build a complex structure in C?

查看:35
本文介绍了使用 C 扩展 Python 时,如何在 C 中动态构建复杂结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个 C 函数,它返回一个元组列表、一个字典列表,或者更好的是,一个我在另一个 python 模块中定义的类的对象列表.

I'd like to make a C function which returns a list of tuples, a list of dicts or even better, a list of objects of a class I defined in another python module.

关于 C API(«The Python/C API»)的文档提到要构建一个复杂的对象,我需要调用 Py_BuildValue 它使用可变数量的参数或 Py_VaBuildValue 使用 va_list 参数.

The documentation on the C API («The Python/C API») mentions that to build a complex object, I need to call to Py_BuildValue which uses a Variable number of parameters or Py_VaBuildValue which uses a va_list argument.

由于 C 不能用可变数量的参数动态调用,所以我不能使用 Py_BuildValue 并且必须使用 Py_VaBuildValue,但正在寻找如何构建一个 va_list 变量,我找到了 没有能力显式填充 va_list告诉我用可变参数函数制作它,这违背了目的......从所做的测试中,我得到的只是分段错误和核心转储.

Since C cannot dynamically make a call with a variable number of arguments, I cannot use Py_BuildValue and must use Py_VaBuildValue, but looking for how to build a va_list variable, I find replies which the There's no ability to fill a va_list explicitly and tells me to make it from a variable parameters function, which defeats the purpose... and from the tests a made, all I get is segmentation faults and core dumps.

那么,我应该如何使用这些功能?

So, how am I Supposed to use those functions ?

推荐答案

您不应该使用这些函数来构建动态大小的数据结构.FAQ 说对任意大小的元组使用 PyTuple_Pack 而不是 Py_BuildValue,但这也是错误的;我不知道为什么这么说.PyTuple_Pack 具有与 Py_BuildValue 相同的可变参数问题.

You're not supposed to use those functions to build dynamically-sized data structures. The FAQ says to use PyTuple_Pack instead of Py_BuildValue for an arbitrary-sized tuple, but that's wrong too; I don't know why it says that. PyTuple_Pack has the same varargs issues as Py_BuildValue.

要从 C 构建可变长度元组,请使用 PyTuple_New 构建未初始化的元组所需的长度,然后遍历索引并使用 设置元素PyTuple_SET_ITEM.是的,这会改变元组.PyTuple_SET_ITEM 可以安全地用于初始化尚未暴露给其他代码的新元组.另外,请注意 PyTuple_SET_ITEM 会窃取对新元素的引用.

To build a variable-length tuple from C, use PyTuple_New to construct an uninitialized tuple of the desired length, then loop over the indices and set the elements with PyTuple_SET_ITEM. Yes, this mutates the tuple. PyTuple_SET_ITEM is only safe to use to initialize fresh tuples that have not yet been exposed to other code. Also, be aware that PyTuple_SET_ITEM steals a reference to the new element.

例如,构建一个从 0 到 n-1 的整数元组:

For example, to build a tuple of integers from 0 to 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 一样,如果你没有有列表推导式或序列乘法.

To build a variable-length list from C, you can do the same thing with PyList_New and PyList_SET_ITEM, or you can construct an empty list with PyList_New(0) and append items with PyList_Append, much like you would use [] and append in Python if you didn't have list comprehensions or sequence multiplication.

这篇关于使用 C 扩展 Python 时,如何在 C 中动态构建复杂结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆