python boost boost-python stdvector

boost:: python: lista de Python a std:: vector



boost-python stdvector (4)

Finalmente puedo usar std :: vector en python usando el operador []. El truco es simplemente proporcionar un contenedor en el contenedor C ++ boost que maneja las cosas internas del vector:

#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) ; }

El otro desafío es: ¿Cómo traducir las listas de Python a std :: vectores? Traté de agregar una clase c ++ esperando un parámetro std :: vector como parámetro y agregué el código contenedor correspondiente:

#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) ; }

Pero si lo hago, termino con el siguiente 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> >)

¿Alguien puede decirme cómo puedo acceder a las listas de Python dentro de mi función c ++?

Gracias, Daniel


Basándome en las respuestas anteriores, creé un ejemplo de acceso a las listas de Python en C ++ y también devolviendo una lista de Python desde una función de C ++:

#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); }

Para ver un ejemplo de compilación y un script de prueba python, eche un vistazo here

Gracias Arlaharen & rdesgroppes por los punteros (juego de palabras no previsto).


Esto es lo que uso:

#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 >( ) ); }

Si considera que el tipo de entrada (py :: object) es demasiado liberal, siéntase libre de especificar tipos más estrictos (py :: list en su caso).


Para obtener la conversión automática de las listas de Python, debe definir un convertidor, que

  1. comprueba si la lista es convertible a su tipo (es decir, que es una secuencia, además, también puede verificar si todos los elementos son del tipo requerido, pero eso también se puede manejar en el segundo paso)
  2. devuelve el nuevo objeto, si el primer paso fue exitoso; lanzar una excepción si un elemento de secuencia no es convertible a lo que necesita.

No puedo encontrar nada más que mi código, puede copiar y pegar esta plantilla (está especializada al final de ese archivo para varios tipos contenidos).


Para que su método C ++ acepte las listas de Python, debe usar boost::python::list

void massadd(boost::python::list& ns) { for (int i = 0; i < len(ns); ++i) { add(boost::python::extract<double>(ns[i])); } }