将C ++成员向量包装为Python OrderedDict

时间:2016-12-03 21:56:08

标签: python c++ vector swig ordereddictionary

编辑更好地解释问题:

我有一个类似的课程:

#include <vector>
#include <utility>
#include <string>

class Test
{
public:
    std::vector<std::pair<std::string, std::string>> a;
    bool read(const std::string& path);
    bool write(const std::string& path);
}

我想修改由Swig for Python创建的setter和getter,以便我可以获取/设置有序字典。

目前,在界面文件中使用以下内容:

%include "stl.i"

%template(string_pair) std::pair<std::string, std::string>;
%template(string_pair_vec) std::vector< std::pair<std::string, std::string>>;

我可以编写如下代码的Python代码:

from collections import OrderedDict

t = Test()
d = OrderedDict(t.a)
t.a = string_pair_vec([(k,v) for k,v in d.items()])

但是,当修改OrderedDict时,用户必须正确管理t.a以反映更改..所以我认为直接在SWIG生成的代码中管理这些操作可能更好。

根据我目前的理解,如果我正在处理一个简单的dict,我可以使用typemap(类似这样的内容:%typemapping of a C++ Library for Python Interface)来完成,但是OrderedDict用纯Python实现。

所以我目前的直觉是我必须在我的界面文件中使用这样的东西:

%pythonappend Test::a %{
   #Code to create and populate the ordered dict
%}

但上面的签名不起作用(或者,更好的是,我不知道如何识别setter和getter)。

有人有这样的经历吗?

1 个答案:

答案 0 :(得分:3)

In such cases I would advise against making your interface use ordereddict per se, and instead make a "compatible" interface which in Python would work like this:

t = Test()
t.a = ordereddict(...).items()
print(ordereddict(t.a))

That is, rather than mapping your vector to an ordereddict directly, make the getter return a sequence (list or generator) of 2-tuples, and make the setter accept a sequence of 2-tuples. This is more flexible, and lets users of the API store the values in a Python list if they prefer (which is much more similar to how you're storing them in C++). And it sidesteps the issue of how to get ordereddict working in SWIG.