我在c ++中有一个从python调用的方法,需要返回一个python列表对象。
我已经创建了这个方法,它附加到一个公开的类,现在可以从python中调用...(它返回void)。
所以问题是,如何从中创建一个python列表:
std::vector<std::string> results;
我并不是真的从这个文档中了解构造函数的工作原理:
http://www.boost.org/doc/libs/1_37_0/libs/python/doc/v2/list.html
另外......我真的不想返回那种包装的矢量......我只是想用矢量中的字符串值创建一个新的python列表。
我很抱歉,如果这是重复的......我找到了很多关于矢量问题的列表,但我找不到任何关于创建新的python列表的信息。
我可以扩展这个问题,以包括其他一些问题:
从:std::map<std::string, std::string>
创建一个新的python字典,依此类推。
答案 0 :(得分:58)
boost::python
已包含包装矢量和地图的功能。这是向量的示例代码,因为您可以看到传递和返回列表非常简单:
// C++ code
typedef std::vector<std::string> MyList;
class MyClass {
MyList myFuncGet();
void myFuncSet(const Mylist& list);
// stuff
};
// Wrapper code
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
using namespace boost::python;
BOOST_PYTHON_MODULE(mymodule)
{
class_<MyList>("MyList")
.def(vector_indexing_suite<MyList>() );
class_<MyClass>("MyClass")
.def("myFuncGet", &MyClass::myFuncGet)
.def("myFuncSet", &MyClass::myFuncSet)
;
}
地图与矢量非常相似,并在本文中进行了描述: Boost::Python- possible to automatically convert from dict --> std::map?
不幸的是,boost::python
目前不包含包装列表的工具。您可以手动创建包装器,但我没有时间来回答这个问题。我可以今天或明天发布。我很欣赏关于这个特定问题的新问题,因为答案将非常广泛,可能超出了本文的范围。我只是避免使用列表并使用向量。
答案 1 :(得分:13)
我有这个函数使用迭代器将std::vector
转换为py::list
:
namespace py = boost::python;
template<class T>
py::list std_vector_to_py_list(const std::vector<T>& v)
{
py::object get_iter = py::iterator<std::vector<T> >();
py::object iter = get_iter(v);
py::list l(iter);
return l;
}
答案 2 :(得分:8)
如果你只想手动创建python列表(并且让函数返回py :: list而不是vector),那就这样做:
/* using namespace std; namespace py=boost::python;
#define FOREACH BOOST_FOREACH
*/
vector<string> ss;
py::list ret;
FOREACH(const string& s, ss) ret.append(s);
return s;
对于自动转换,定义从python列表到c ++的向量转换器以及从c ++到python列表的转换器 - 我刚刚在Instantiating shared_ptr's in boost::python(回复的第二部分)写了这个;这样,你得到真正的python列表。
自动转换的另一种可能性(我没有经验)是使用indexing_suite,它将vector<string>
包装为python中的特殊类,作为此处提到的同事。
答案 3 :(得分:6)
来自http://gist.github.com/octavifs/5362272:
// Converts a C++ vector to a python list
template <class T>
boost::python::list toPythonList(std::vector<T> vector) {
typename std::vector<T>::iterator iter;
boost::python::list list;
for (iter = vector.begin(); iter != vector.end(); ++iter) {
list.append(*iter);
}
return list;
}
答案 4 :(得分:1)
FWIW,这是一个与eudoxos解决方案相同的模板化函数:
namespace py = boost::python;
template<class T>
py::list std_vector_to_py_list(const std::vector<T>& v)
{
py::list l;
typename std::vector<T>::const_iterator it;
for (it = v.begin(); it != v.end(); ++it)
l.append(*it);
return l;
}