Python NamedTuple to C++ Struct

Python NamedTuple to C++ Struct

本文关键字:Struct C++ to NamedTuple Python      更新时间:2023-10-16

我已经在网上搜了好几个小时了。有人知道如何解析从python函数返回的namedtuple到结构体或单独的变量吗?我有麻烦的部分是从返回的指针中获取数据。我正在使用PyObject_CallFunction()调用调用嵌入在c++中的python函数,我不知道一旦我有PyObject*返回的数据该怎么办。

我使用Python 2.7作为参考。

编辑:我最终把我试图在Python和c++中做的所有功能都移到了Python中。我将在不久的将来更新关于尝试这个问题评论中建议的策略。

我正在调用嵌入在c++中的python函数PyObject_CallFunction()调用后,我不知道该怎么做

将PyObject*转换为返回的数据。

namedtuple是一个元组子类,它额外地将元组元素公开为命名属性。这意味着您可以选择以obj[position]还是obj.attribute的方式访问其数据。后者通常更具可读性,但前者可以很好地与元组解包结合使用。在Python/C中,可能更容易将其作为元组访问,因为这样您可以使用便利函数PyArg_ParseTuple,如注释中所示。

要提取对象的任意属性(不一定是namedtuple),可以调用PyObject_GetAttrString。给定一个描述点的对象,提取像x这样的属性可能如下所示:

PyObject *point = ...;  // assume we get a new reference to point
if (!point)
  return NULL;
PyObject *x = PyObject_GetAttrString(point, "x");
if (!x) {
  // obj.x raised, possibly because point is of a different type
  Py_DECREF(point);
  return NULL;
}
double x_val = PyFloat_AsDouble(x);
Py_DECREF(x);     // x not used below this line
if (x_val == -1 && PyErr_Occurred()) {
  // obj.x is not float or float-like
  Py_DECREF(point);
  return NULL;
}
Py_DECREF(point); // point not used below this line

错误检查和引用计数相当乏味,但它可以通过使用保护类来消除,或者更好的是,使用其他人编写的类,如Boost.Python。

namedtuple完全在Python中实现。您可以在collections.py中看到它的完整源代码。它很短。要记住的是,namedtuple本身是一个函数,它在调用它的框架中创建一个类,然后返回这个类(不是这个类的实例)。然后使用这个返回的类来创建实例。所以你得到的对象不是你想传递给c++的如果你想传递单个实例。

c++在编译时创建struct定义。namedtuple在运行时创建命名元组类。如果您想将它们绑定到c++结构体,可以使用PyObject在c++内部创建新创建的类实例,并在编译时将它们分配给struct元素。或者在Python中创建新创建的类实例,并将它们传递给c++。

或者您可以使用_asdict方法(由namedtuple工厂方法为它构建的所有类提供)并将其传递给c++,然后将运行时定义的数据绑定到编译时定义的数据。

如果你真的想在c++中做大量的工作,你也可以使用Struct模块而不是使用namedtuple。

namedtuple实际上是Python的瑞士军刀,用于保存在Python中的数据。它提供了位置访问,命名访问,所有元素也都是"属性"(所以它们有fget访问方法,可以在映射,过滤器等中使用,而不必编写自己的lambdas)。

它是用来做DB绑定之类的事情的(当你不知道运行时哪些列会在那里时)。在将数据从一种格式转换为另一种格式时,它没有OrderedDict那么笨拙。当以这种方式使用时,处理字符串的开销与实际访问db(甚至嵌入)相比微不足道。但是我不会将namedtuple用于用于计算的大型结构体数组