【问题标题】:How to make my C++ class exposed by SWIG behaving like a tuple in python?如何让 SWIG 公开的 C++ 类表现得像 python 中的元组?
【发布时间】:2021-03-29 05:44:09
【问题描述】:

我有一个非常简单的 C++ 类,它拥有一个 std::vector。我想通过 SWIG 向 python 公开这个类:

arr.hpp:

#include <vector>
class Arr
{
public:
  inline Arr() : _v() { }
  inline void add(double v) { _v.push_back(v); }
  inline double get(unsigned int i) const { return _v[i]; }
  inline const std::vector<double>& getVector() const { return _v; }
private:
  std::vector<double> _v;
};

arr.i:

%module pyarr

%include <std_vector.i>

namespace std {
%template(VectorDouble) vector<double>;
};

%include Arr.hpp
%{
  #include "Arr.hpp"
%}

生成文件:

swig -c++ -python -naturalvar -o arr_wrap.cpp arr.i
g++ -std=c++11 -fpic -shared arr_wrap.cpp -I/usr/include/python3.5m -o _pyarr.so

test_arr.py:

#!/usr/bin/python3

from pyarr import *

a = Arr()
a.add(1.2)
a.add(2.3)
print("v[0]=",a.get(0))
print("v[1]=",a.get(1))
print("v as vector=",a.getVector())
print("v=",a)

当我执行 test_arr.py 脚本时,我得到:

python3 test_arr.py

v[0]= 1.2
v[1]= 2.3
v as vector= (1.2, 2.3)
v= <pyarr.Arr; proxy of <Swig Object of type 'Arr *' at 0x7f6f6fa4bf00> >

我必须做些什么才能让我的 Arr 类表现得像一个 python 元组?所以最后一行将是:

v= (1.2, 2.3)

[编辑]:我的问题不仅是为了显示目的,也是为了绘制直方图或初始化 numpy 数组等...

请注意,按照此处建议的答案 (How to use a Python list to assign a std::vector in C++ using SWIG?),我尝试在 swig 命令行中使用和不使用 %naturalvar。

【问题讨论】:

    标签: python c++ vector swig


    【解决方案1】:

    您可以扩展该类以包含 __repr__ 函数,以便 Python 将根据需要显示 Arr 类:

    更新了 arr.i:

    %module pyarr
    
    %{
        #include <string>
        #include <sstream>
        #include "Arr.hpp"
    %}
    
    %include <std_vector.i>
    %include <std_string.i>
    
    namespace std {
    %template(VectorDouble) vector<double>;
    };
    
    %extend Arr {
        std::string __repr__()
        {
            std::ostringstream ss;
            auto v = $self->getVector();
            auto size = v.size();
            ss << "(";
            if(size > 0) {
                ss << v[0];
                for(size_t i = 1; i < size; ++i)
                    ss << ", " << v[i];
            }
            ss << ")";
            return ss.str();
        }
    }
    
    %include "Arr.hpp"
    

    test_arr.py 的输出:

    v[0]= 1.2
    v[1]= 2.3
    v as vector= (1.2, 2.3)
    v= (1.2, 2.3)
    

    【讨论】:

    • 非常感谢马克的回答。你的提议回答了我的问题,但我真的需要将 Arr 视为一个元组。不仅用于显示目的,还用于绘制直方图或初始化 numpy 数组。我已将我的问题编辑得更准确。
    • @McClain 你有一个带有 getVector 方法的元组。它不能同时作为一个类和一个元组。也许您想要将输入参数从元组转换为 Arr 并将 Arr 类型返回为元组的类型映射?
    • @McClain。如果您希望能够从 C++ 输出 python 元组,用另一个 c++ 类包装 std::vector 不是要走的路。正如 Mark 建议的那样,您应该使用类型映射,请参阅 stackoverflow.com/questions/52960876/…。你也可以看看numpy.i
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-25
    • 2021-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多