首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python*促进::python::object

Python*促进::python::object
EN

Stack Overflow用户
提问于 2015-07-17 05:06:14
回答 2查看 6.8K关注 0票数 8

我正试图在C++中构建一个Python模块,该模块将2D向量转换为Numpy 2D数组。这里不正确的地方--大概需要从PyObject*对一个boost python对象进行一些转换。

代码语言:javascript
复制
boost::python::object build_day(int year, int day) {

  PyObject* arr;
  const int HEIGHT = 5;
  const int WIDTH = 5;

  std::vector<std::vector<float> > array(WIDTH, std::vector<float>(HEIGHT));

  npy_intp dims[2] = {WIDTH, HEIGHT};
  arr = PyArray_SimpleNewFromData(2, dims, NPY_FLOAT, &array);

  return arr; 
}

BOOST_PYTHON_MODULE(sumpar) {
  using namespace boost::python;
  def("build_day", build_day, args("year", "day"));
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-08-29 22:55:25

boost::python::object为Python对象提供了一个通用接口。要从PyObject*构建boost::python::handle<>,首先必须构造一个boost::python::handle<>,它本质上是一个智能指针,用于管理引用计数的PyObject*对象(PyObject*或派生类型)。人们通常在Boost.Python的高级代码和Python/C之间的边界之间使用handle<>

代码语言:javascript
复制
namespace python = boost::python;
PyObject* py_object = get_py_object();
python::handle<> handle(py_object);
boost::python object(handle);

请注意,handle将共享PyObject*的所有权,并且在销毁过程中,它将减少它正在管理的PyObject的引用计数。因此,在构建过程中,重要的是指定handle<>是否需要增加PyObject*的引用计数。

如果PyObject已经增加了它的引用计数,那么使用:

代码语言:javascript
复制
namespace python = boost::python;
PyObject* py_object = ...;
python::handle<> handle(py_object);
python::object object(handle);

如果PyObject没有增加它的引用计数,而且句柄必须这样做,那么在构造过程中使用borrowed()函数:

代码语言:javascript
复制
namespace python = boost::python;
PyObject* py_object = ...;
python::handle<> handle(python::borrowed(py_object));
python::object object(handle);

下面是一个完整的示例示范,它从一个PyObject*构造一个boost::python::object

代码语言:javascript
复制
#include <vector>
#include <boost/python.hpp>

// Mocks...
enum { NPY_FLOAT };
typedef int npy_intp;
PyObject* PyArray_SimpleNewFromData(int, npy_intp*, int, void*)
{
  return PyString_FromString("hello world");
}

boost::python::object build_day(int year, int day)
{
  const int HEIGHT = 5;
  const int WIDTH = 5;

  std::vector<std::vector<float> > array(
      WIDTH, std::vector<float>(HEIGHT));

  npy_intp dims[2] = {WIDTH, HEIGHT};

  namespace python = boost::python;
  PyObject* arr = PyArray_SimpleNewFromData(2, dims, NPY_FLOAT, &array);
  python::handle<> handle(arr);
  return python::object(handle);
}

BOOST_PYTHON_MODULE(example)
{
  namespace python = boost::python;
  python::def("build_day", &build_day, python::args("year", "day"));
}

互动用法:

代码语言:javascript
复制
>>> import example
>>> day = example.build_day(1, 2);
>>> assert(day)

注意,要创建一个最小的完整示例,上面的示例有一个模拟的PyArray_SimpleNewFromData(),它只是返回Python。查阅文档以确定是否借用了PyObject*,以及对象与其参数之间是否存在任何生存期要求,这一点非常重要。对于PyArray_SimpleNewFromData(),返回的PyObject*

  • 它的参考计数已经增加了。
  • 提供给数组的底层内存的生存期必须至少与返回的PyObject一样长。原始问题中的build_day()函数不能满足这一要求。
票数 7
EN

Stack Overflow用户

发布于 2015-08-11 20:27:56

我的建议是使用boost::python提供的变量和对象,所以如果您想将数组返回到python,那么最好使用boost::python::dict,类似于.

代码语言:javascript
复制
boost::python::dict arr;

int i = 0;
for (auto &item: array) {
    arr[i] = item;
    ++i;
}

return arr;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31468724

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档