如何在我的C ++ __getitem__函数中处理切片(由SWIG使用)

时间:2011-11-21 20:45:48

标签: c++ python swig

我正在为C ++类开发Python绑定,扩展了std::vector实例化。为了让Python下标操作符为这个类工作,我添加了__getitem__函数,如下所示(我删除了不相关的代码和错误处理):

class Column;

typedef vector<Column*> MetaDataBase;

class MetaData : public MetaDataBase {
public:

#ifdef SWIGPYTHON
Column* __getitem__(int i) { return (*this)[i]; }
#endif
};

以上在Python中可以正常访问单个元素,但它不适用于切片。

好的,所以我理解我需要将函数的参数类型更改为PyObject *并使用PySlice_Check来查看函数是否应该返回PyList

这没关系,没问题。但是因为我有时必须从函数返回PyList,所以__getitem__返回值的类型也必须是PyObject*,我不能依赖SWIG来转换我的C ++类型({ {1}})到包装类。此外,在创建切片时,我需要先“手动”将Column *转换为Column*,然后再将其插入PyList。

我该怎么做?

1 个答案:

答案 0 :(得分:3)

对于使用SWIG + Python的std::vector,我认为有一个更简单的解决方案。 SWIG的Python代码生成已经支持在包装一些STL容器方面做得非常好。

如果您添加到模块界面的开头:

%include "pyabc.i"
%include "std_vector.i" // Assuming you don't already

在某处,如果你还没有这样做:

%template(MetaDataBase) std::vector<Column*>;

然后这将导致包裹的std::vector满足Python MutableSequence的要求。 (我认为这应该足以实现你在Python方面寻找的东西,你可能需要用-extranative来调用SWIG。

另外值得注意的是 - 对于您当前的__getitem__,您可以使用以下内容在SWIG界面文件中声明和定义它:

%extend MetaData {
   Column* __getitem__(int i) { return (*self)[i]; }
};

这使您可以在不使用SWIG + Python特定代码“污染”“普通”头文件的情况下执行此操作。