boost::python: Python liste de std::vector
enfin je suis capable d'utiliser std::vector en python en utilisant l'opérateur []. Le truc est de fournir simplement un conteneur dans le boost C++ wrapper qui gère les trucs vectoriels internes:
#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)
;
}
L'autre défi est: comment faire traduire les listes en python std::les vecteurs? J'ai essayé d'ajouter une Classe C++ en attendant un paramètre std::vector et j'ai ajouté le code d'enrubannage correspondant:
#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)
;
}
mais si je le fais, je me retrouve avec le suivant Stimuler.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> >)
quelqu'un peut-il me dire comment je peux accéder aux listes python dans ma fonction c++?
Merci, Daniel
4 réponses
pour que votre méthode c++ accepte les listes Python, vous devez utiliser boost::python::list
void massadd(boost::python::list& ns)
{
for (int i = 0; i < len(ns); ++i)
{
add(boost::python::extract<double>(ns[i]));
}
}
Voici ce que j'utilise:
#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 vous trouvez le type d'entrée (py::object) trop libéral, n'hésitez pas à spécifier des types plus stricts (PY::list dans votre cas).
basé sur les réponses ci-dessus, j'ai créé un exemple d'accès aux listes python en C++ ainsi que de retour d'une liste python à partir d'une fonction 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);
}
Pour construire un exemple et un test de script python prendre un coup d'oeil ici
merci à Arlaharen & rdesgroppes pour les pointeurs (jeu de mots non prévu).
pour obtenir la conversion automatique des listes python, vous devez définir un convertisseur, qui
- vérifie si la liste est convertible à votre type (c'est-à-dire qu'il s'agit d'une séquence; en outre, vous pouvez également vérifier si tous les éléments sont du type requis, mais qui peut être manipulé dans la deuxième étape aussi bien)
- renvoie le nouvel objet, si la première étape a réussi; jeter l'exception si un élément de séquence n'est pas convertible à ce dont vous avez besoin.
je ne pouvez pas trouver quelque chose d'autre que mon code, vous pouvez copier-coller ce modèle (il est spécialisé à la fin de ce fichier pour divers types contenus).