2012-03-07 4 views
1

У меня есть функция в C++, которая возвращает объект vector<vector<double> >. Я обернул его для Python с помощью Swig. Когда я его вызываю, я не могу впоследствии изменить выход функции с использованием векторных методов или push_back().Python swig-wrapped vector of of doubles появляется как Tuple

Когда я пытаюсь это сделать, я получаю сообщение об ошибке, что объект 'tuple' не имеет атрибута 'resize' или 'push_back'. Переводит ли Swig векторы в объекты Tuple, когда я взаимодействую с ними в Python? Если это так, то я предполагаю, что вывод этой функции в Python является неизменным, что является проблемой. Я могу передать этот объект в обернутые методы, которые принимают вектор векторов двойников. Я просто не могу возиться с ним, используя векторные методы из Python. Любые объяснения, почему это так, или идеи об условиях работы, будут оценены.

Вот мой файл swig для справки. линии шаблонов STL должны располагаться ближе к концу:

/* SolutionCombiner.i */ 
%module SolutionCombiner 
%{ 
    /* Put header files here or function declarations like below */ 
    #include "Coord.hpp" 
    #include "MaterialData.hpp" 
    #include "FailureCriterion.hpp" 
    #include "QuadPointData.hpp" 
    #include "ModelSolution.hpp" 
    #include "ExclusionZone.hpp" 
    #include "CriticalLocation.hpp" 
    #include "FailureMode.hpp" 
    #include "ExecutiveFunctions.hpp" 

    #include <fstream> 
    #include <iostream> 
%} 
%{ 
    #define SWIG_FILE_WITH_INIT 
    std::ostream& new_ofstream(const char* FileName){ 
     return *(new std::ofstream(FileName)); 
    } 

    std::istream& new_ifstream(const char* FileName){ 
     return *(new std::ifstream(FileName)); 
    } 

    void write(std::ostream* FOUT, char* OutString){ 
     *FOUT << OutString; 
    } 

    std::ostream *get_cout(){return &std::cout;} 
%} 

%include "std_vector.i" 
%include "std_string.i" 
%include "std_set.i" 
%include "../../source/Coord.hpp" 
%include "../../source/MaterialData.hpp" 
%include "../../source/FailureCriterion.hpp" 
%include "../../source/QuadPointData.hpp" 
%include "../../source/ModelSolution.hpp" 
%include "../../source/ExclusionZone.hpp" 
%include "../../source/CriticalLocation.hpp" 
%include "../../source/FailureMode.hpp" 
%include "../../source/ExecutiveFunctions.hpp" 

namespace std { 
    %template(IntVector) vector<int>; 
    %template(DoubleVector) vector<double>; 
    %template(DoubleVVector) vector<vector<double> >; 
    %template(DoubleVVVector) vector<vector<vector<double> > >; 
    %template(SolutionVector) vector<ModelSolution>; 
    %template(CritLocVector) vector<CriticalLocation>; 
    %template(CritLocVVector) vector<vector<CriticalLocation> >; 
    %template(ModeVector) vector<FailureMode>; 
    %template(IntSet) set<int>; 
} 
std::ofstream& new_ofstream(char* FileName); 
std::ifstream& new_ifstream(char* FileName); 
std::iostream *get_cout(); 

ответ

1

Да, вектор шаблон возвращает неизменный Python кортеж. Возможно, вы можете изменить реализацию std_vector.i для возврата списков, но, вероятно, есть веская причина для выбора. Вы можете конвертировать их в списки, чтобы вы могли управлять ими в Python:

>>> x.func() 
((1.5, 2.5, 3.5), (1.5, 2.5, 3.5), (1.5, 2.5, 3.5), (1.5, 2.5, 3.5)) 
>>> [list(n) for n in x.func()] 
[[1.5, 2.5, 3.5], [1.5, 2.5, 3.5], [1.5, 2.5, 3.5], [1.5, 2.5, 3.5]] 

Примечание: Я сделал функцию выборки, возвращенный vector<vector<double>> в качестве теста.