boost::python:Python 列表到 std::vector
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3761391/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
boost::python: Python list to std::vector
提问by dmorlock
Finally I'm able to use std::vector in python using the [] operator. The trick is to simple provide a container in the boost C++ wrapper which handles the internal vector stuff:
最后,我可以使用 [] 运算符在 python 中使用 std::vector 。诀窍是简单地在 boost C++ 包装器中提供一个容器来处理内部向量:
#include <boost/python.hpp>
#include <vector>
class world
{
std::vector<double> myvec;
void add(double n)
{
this->myvec.push_back(n);
}
std::vector<double> show()
{
return this->myvec;
}
};
BOOST_PYTHON_MODULE(hello)
{
class_<std::vector<double> >("double_vector")
.def(vector_indexing_suite<std::vector<double> >())
;
class_<World>("World")
.def("show", &World::show)
.def("add", &World::add)
;
}
The other challenge is: Howto translate python lists into std::vectors? I tried to add a c++ class expecting a std::vector as parameter and added the corresponding wrapper code:
另一个挑战是:如何将 python 列表转换为 std::vectors?我尝试添加一个需要 std::vector 作为参数的 c++ 类并添加了相应的包装器代码:
#include <boost/python.hpp>
#include <vector>
class world
{
std::vector<double> myvec;
void add(double n)
{
this->myvec.push_back(n);
}
void massadd(std::vector<double> ns)
{
// Append ns to this->myvec
}
std::vector<double> show()
{
return this->myvec;
}
};
BOOST_PYTHON_MODULE(hello)
{
class_<std::vector<double> >("double_vector")
.def(vector_indexing_suite<std::vector<double> >())
;
class_<World>("World")
.def("show", &World::show)
.def("add", &World::add)
.def("massadd", &World::massadd)
;
}
But if doing so, I end up with the following Boost.Python.ArgumentError:
但如果这样做,我最终会得到以下 Boost.Python.ArgumentError:
>>> w.massadd([2.0,3.0])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Boost.Python.ArgumentError: Python argument types in
World.massadd(World, list)
did not match C++ signature:
massadd(World {lvalue}, std::vector<double, std::allocator<double> >)
Can anybody tell me how I can access python lists within my c++ function?
谁能告诉我如何在我的 C++ 函数中访问 python 列表?
Thanks, Daniel
谢谢,丹尼尔
采纳答案by Arlaharen
To make your C++ method accept Python lists you should use boost::python::list
要使您的 C++ 方法接受您应该使用的 Python 列表 boost::python::list
void massadd(boost::python::list& ns)
{
for (int i = 0; i < len(ns); ++i)
{
add(boost::python::extract<double>(ns[i]));
}
}
回答by eudoxos
To get automatic conversion from python lists, you have to define a converter, which
要从 python 列表中自动转换,你必须定义一个转换器,它
- checks if the list is convertible to your type (i.e. that it is a sequence; additionally, you can also check whether all elements are of required type, but that can be handled in the second step as well)
- returns the new object, if the first step succeeded; throw exception if a sequence element is not convertible to what you need.
- 检查列表是否可转换为您的类型(即它是一个序列;此外,您还可以检查是否所有元素都是必需的类型,但这也可以在第二步中处理)
- 如果第一步成功,则返回新对象;如果序列元素无法转换为您需要的元素,则抛出异常。
I can't find now anything else than my code, you can copy&paste this template(it is specialized at the end of that file for various contained types).
除了我的代码之外,我现在找不到任何其他内容,您可以复制并粘贴此模板(它专门用于该文件的末尾,用于各种包含的类型)。
回答by rdesgroppes
Here's what I use:
这是我使用的:
#include <boost/python/stl_iterator.hpp>
namespace py = boost::python;
template< typename T >
inline
std::vector< T > to_std_vector( const py::object& iterable )
{
return std::vector< T >( py::stl_input_iterator< T >( iterable ),
py::stl_input_iterator< T >( ) );
}
Should you find the input type (py::object) too liberal, feel free to specify stricter types (py::list in your case).
如果您发现输入类型 (py::object) 过于宽松,请随意指定更严格的类型(在您的情况下为 py::list)。
回答by Andreas Grivas
Based on the above answers I created an example of accessing python lists in C++ as well as returning a python list from a C++ function:
基于上述答案,我创建了一个在 C++ 中访问 python 列表以及从 C++ 函数返回 python 列表的示例:
#include <boost/python.hpp>
#include <string>
namespace py = boost::python;
// dummy class
class drow{
public:
std::string word;
drow(py::list words);
py::list get_chars();
};
// example of passing python list as argument (to constructor)
drow::drow(py::list l){
std::string w;
std::string token;
for (int i = 0; i < len(l) ; i++){
token = py::extract<std::string>(l[i]);
w += token;
}
this -> word = w;
}
// example of returning a python list
py::list drow::get_chars(){
py::list char_vec;
for (auto c : word){
char_vec.append(c);
}
return char_vec;
}
// binding with python
BOOST_PYTHON_MODULE(drow){
py::class_<drow>("drow", py::init<py::list>())
.def("get_chars", &drow::get_chars);
}
For a build example and a test python script take a look here
有关构建示例和测试 python 脚本,请查看此处
Thank you Arlaharen & rdesgroppes for the pointers (pun not intended).
谢谢 Arlaharen & rdesgroppes 的指点(不是双关语)。

