gpt4 book ai didi

C++ 列表 到 Python 列表

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:03:03 27 4
gpt4 key购买 nike

我正在为现有的 C++ 库编写包装器,该库使用列表,其中 T 是自定义结构。我被建议使用 vector 而不是列表,但我试图避免修改库。

为了更好地理解这个场景,我做了一个简单的应用程序,使用一个列表作为代理来注册一个到 python 的转换(只读就可以)。

我当前的实现编译正常,python 导入正常,可以创建对象,但是当我调用数据成员时,它出错。

python shell 输出:

In [1]: import my_list

In [2]: x = my_list.Bob()

In [3]: x.foos
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-2f015d13a87d> in <module>()
----> 1 x.foos

TypeError: No Python class registered for C++ class std::list<int, std::allocator<int> >

C++ 文件:

#include <list>
#include <boost/python.hpp>

#include <boost/foreach.hpp>
#ifndef FOREACH
#define FOREACH BOOST_FOREACH
#endif

using namespace std;
using namespace boost::python;

template<typename T>
struct list_to_list
{
static PyObject* convert(const std::list<T>& src)
{
boost::python::list result;
FOREACH (const T& val, src)
{
result.append(val);
}

return incref(result.ptr());
}
};

struct Bob
{
std::list<int> foos;
};

BOOST_PYTHON_MODULE(my_list)
{
using namespace boost::python;

to_python_converter<std::list<int>, list_to_list<int> >();

class_<Bob>("Bob")
.def_readonly("foos", &Bob::foos)
;
}

我错过了什么吗?

最佳答案

FAQ 中所述,通过 def_readonly()def_readwrite()add_property() 使用默认策略公开的属性将不会使用自定义转换器。要解决此问题,请将 def_readonly()def_readwrite() 替换为 add_property(),提供 boost::python::return_value_policy类型为 boost::python::return_by_value .

在原始代码中,它将是:

BOOST_PYTHON_MODULE(my_list)
{
using namespace boost::python;

to_python_converter<std::list<int>, list_to_list<int> >();

class_<Bob>("Bob")
.add_property("foos", make_getter(&Bob_foos,
return_value_policy<return_by_value>()))
;
}

这是一个完整的例子:

#include <list>
#include <boost/assign/list_of.hpp>
#include <boost/foreach.hpp>
#include <boost/python.hpp>

namespace python = boost::python;

/// @brief Type to convert from an iterable to a Python list.
template <typename T>
struct list_to_list
{
static PyObject* convert(const std::list<T>& container)
{
python::list result;
BOOST_FOREACH(const T& value, container)
result.append(value);
return python::incref(result.ptr());
}
};

/// @brief mockup type.
struct Spam
{
Spam()
{
foos = boost::assign::list_of(1)(2)(3)(5);
}

std::list<int> foos;
};

BOOST_PYTHON_MODULE(example)
{
// Enable std::list<int> to Python list conversion.
python::to_python_converter<std::list<int>, list_to_list<int> >();

python::class_<Spam>("Spam")
.add_property("foo", python::make_getter(&Spam::foos,
python::return_value_policy<python::return_by_value>()))
;
}

以及由此产生的用法:

>>> import example
>>> spam = example.Spam()
>>> spam.foo
[1, 2, 3, 5]

关于C++ 列表<T> 到 Python 列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19597087/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com