2010-09-21 21 views
20

अंत में मैं [] ऑपरेटर का उपयोग कर पायथन में std :: वेक्टर का उपयोग करने में सक्षम हूं। चाल बढ़ावा सी ++ आवरण जो आंतरिक वेक्टर सामान संभालती में एक कंटेनर प्रदान सरल करने के लिए है:बूस्ट :: पायथन: पायथन सूची std :: 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) 
    ; 
} 

अन्य चुनौती है: Howto std :: वैक्टर में अजगर सूचियों अनुवाद न करें? मैं एक std :: पैरामीटर के रूप में वेक्टर की उम्मीद कर एक 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) 
    ; 
} 

लेकिन ऐसा करते हैं, मैं निम्नलिखित 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> >) 

क्या कोई मुझे बता सकता है कि मैं अपने सी ++ फ़ंक्शन के भीतर पाइथन सूचियों का उपयोग कैसे कर सकता हूं?

धन्यवाद, डैनियल

उत्तर

23

अपने सी ++ विधि स्वीकार अजगर को सूचीबद्ध करता है, तो आप एक कनवर्टर, को परिभाषित करने के लिए है आप boost::python::list

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

'बूस्ट :: पायथन :: सूची' विषम हो सकता है, और आप 'निकालने' से अपवादों को पकड़ने के लिए आह्वान करते हैं। – eudoxos

+0

मेरी माफी, 'निकालने' से अपवाद का स्वचालित रूप से पायथन में अनुवाद किया जाएगा। माफ़ कीजिये। – eudoxos

+4

हाँ अच्छा और सरल करने के लिए, बस बूस्ट पायथन दस्तावेज इतना खराब है, और ऑपरेटर [] एक टेम्पलेट ऑब्जेक्ट_ऑपरेटर्स में छिपी हुई है पदानुक्रम को कई परतें और स्पष्ट रूप से एक ऑपरेशन एक सूची नहीं है। मुझे उनकी वेबसाइट प्रलेखन अब और अधिक अनुकूल नहीं मिला है। लेंस() बाहरी विधि बनाना उतना अच्छा नहीं है जितना लगता है कि यह या तो है। इसके अलावा यह फिर से शुरू करने का एकमात्र तरीका है? – CashCow

1

का उपयोग करना चाहिए अजगर सूचियों से स्वचालित रूपांतरण प्राप्त करने के लिए बनाने के लिए जो

  1. चेक करता है कि सूची आपके प्रकार में परिवर्तनीय है (यानी कि यह एक अनुक्रम है; इसके अतिरिक्त, आप यह भी जांच सकते हैं कि सभी तत्व पुनः हैं या नहीं क्वायर प्रकार, लेकिन इसे दूसरे चरण में भी संभाला जा सकता है)
  2. पहला ऑब्जेक्ट लौटाता है, यदि पहला चरण सफल हुआ; यदि अनुक्रम तत्व आपको आवश्यकतानुसार परिवर्तनीय नहीं है तो अपवाद फेंक दें।

अब मैं अपने कोड की तुलना में और कुछ भी नहीं मिल सकता है, आप & पेस्ट this template (यह विभिन्न निहित प्रकार के लिए उस फ़ाइल के अंत में विशेष है) कॉपी कर सकते हैं।

17

यहाँ मैं क्या उपयोग है:

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

आप इनपुट प्रकार (py :: वस्तु) भी उदार, (आपके मामले में py :: सूची) सख्त प्रकार निर्दिष्ट करने में संकोच न खोजना चाहिए।

3

ऊपर जवाब मैं 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); 
} 

निर्माण उदाहरण के लिए और एक परीक्षण अजगर स्क्रिप्ट एक बार देख ले here

प्वाइंटर्स के लिए Arlaharen & rdesgroppes धन्यवाद (पन इरादा नहीं)।