Обернутый в Python вектор вектора двойников выглядит как Tuple - PullRequest
1 голос
/ 07 марта 2012

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

Когда я пытаюсь это сделать, я получаю сообщение об ошибке, что у объекта '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 Ответ

1 голос
/ 10 марта 2012

Да, векторный шаблон возвращает неизменный кортеж 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>> в качестве теста.

...