2010-07-13 2 views
1

저는 파이썬에 익숙하지 않습니다. 저는 파이썬을 향상시켜 보았습니다. 매우 보입니다. 인상적입니다. 그러나 소개를 통해 내가 찾을 수 없습니다 어떤 예제, 개체의 벡터는 파이썬 목록/튜플로 반환됩니다.는 python에서 ref 나 value에 의해 벡터를 반환하는 함수를 지원합니까?

예 :이 예를 사용하여 클래스 X, Cont 및 모든 함수를 표시하고 싶습니다. 중요한 비트 등은 오류를 컴파일 리드()) const_ref_x_vec (같은 기능을 노출하는 것을 시도에 value_x_vec을

class X {}; 

    class Cont { 

     ..... 
     // how can this be exposed using boost python 
     const std::vector<X>& const_ref_x_vec() const { return x_vec_;} 
     std::vector<X> value_x_vec() const { return x_vec;} 

     const std::vector<std::string>& const_ref_str_vec() const { return str_vec_;} 
     std::vector<std::string> value_str_vec() const { return str_vec_; } 

     ... 
    private: 
     std::vector<X> x_vec_; 
     std::vector<std::string> str_vec_; 
    }; 

내 자신의 헛된 시도를 파이썬 X의 나 문자열의 벡터를 반환된다.

Google 검색에서 가치 또는 참조에 의해 벡터를 반환하는 지원을 보지 못했습니다. 이것은 심지어 부스트 파이썬으로 가능합니까? 해결 방법이 있습니까? 이 사건에 SWIG를 사용해야합니까?

도움을 주시면 감사하겠습니다.

아브 타

답변

2

당신은 예를 들어이 내 코드에서하고, 명시 적으로 사용할 벡터의 각 종류를 노출해야 파이썬 템플릿 유형을 노출 할 수 없기 때문에 :

일반 템플릿 포장하기 일 :

namespace bp = boost::python; 

inline void IndexError(){ 
    PyErr_SetString(PyExc_IndexError, "Index out of range"); 
    bp::throw_error_already_set(); 
} 

template<class T> 
struct vec_item{ 
    typedef typename T::value_type V; 
    static V& get(T& x, int i){ 
     static V nothing; 
     if(i < 0) i += x.size(); 
     if(i >= 0 && i < int(x.size())) return x[i]; 
     IndexError(); 
     return nothing; 
    } 
    static void set(T& x, int i, V const& v){ 
     if(i < 0) i += x.size(); 
     if(i >= 0 && i < int(x.size())) x[i] = v; 
     else IndexError(); 
    } 
    static void del(T& x, int i){ 
     if(i < 0) i += x.size(); 
     if(i >= 0 && i < int(x.size())) x.erase(x.begin() + i); 
     else IndexError(); 
    } 
    static void add(T& x, V const& v){ 
     x.push_back(v); 
    } 
}; 

그런 다음, 각 컨테이너 :

// STL Vectors: 
    // LineVec 
    bp::class_< std::vector<Line> >("LineVec") 
     .def("__len__", &std::vector<Line>::size) 
     .def("clear", &std::vector<Line>::clear) 
     .def("append", &vec_item< std::vector<Line> >::add, 
       bp::with_custodian_and_ward<1, 2>()) // let container keep value 
     .def("__getitem__", &vec_item< std::vector<Line> >::get, 
      bp::return_value_policy<bp::copy_non_const_reference>()) 
     .def("__setitem__", &vec_item< std::vector<Line> >::set, 
      bp::with_custodian_and_ward<1,2>()) // to let container keep value 
     .def("__delitem__", &vec_item< std::vector<Line> >::del) 
     .def("__iter__", bp::iterator< std::vector<Line> >()) 
    ; 
    // ... 

std::map에 대해서도 비슷한 방법을 사용할 수 있습니다. 글을 쓸 때 wiki.python.org에서 많은 도움을 받았습니다.

8

Autopulated의 이유는 근본적으로 정확했지만 코드가 더 복잡했습니다.

vector_indexing_suite 당신을 위해 모든 일을 할 수는 :

class_< std::vector<X> >("VectorOfX") 
    .def(vector_indexing_suite< std::vector<X> >()) 
    ; 

뿐만 아니라 map_indexing_suite 있습니다.