如何处理我的 C++ 中的切片__getitem__ 函数(由 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++ 类型 (Column *
) 转换为包装类。另外,在创建切片时,我需要“手动”将 Column*
转换为 PyObject*
,然后再将其插入 PyList。
我该怎么做呢?
I am developing Python bindings for a C++ class which extends a std::vector
instantiation. To get a Python subscript operator working for this class I added __getitem__
function looking as follows (I cut irrelevant code and error handling):
class Column;
typedef vector<Column*> MetaDataBase;
class MetaData : public MetaDataBase {
public:
#ifdef SWIGPYTHON
Column* __getitem__(int i) { return (*this)[i]; }
#endif
};
The above works all right in Python for accessing single elements, but it does not work for slices.
OK, so I understand I need to change type of the function's parameter to PyObject *
and use PySlice_Check
to see if the function is supposed to return a PyList
.
This is fine, no problem with that. But because I have to return PyList
from the function sometimes, the type of the __getitem__
return value has to be PyObject*
as well and I cannot rely on SWIG to convert my C++ type (Column *
) to a wrapper class. Also, when creating a slice, I need to 'manually' convert Column*
to PyObject*
before inserting it into the PyList.
How can I do it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为对于带有 SWIG+Python 的
std::vector
来说,有一个更简单的解决方案。 SWIG 的 Python 代码生成已经支持很好地包装一些 STL 容器。如果您在模块接口的开头添加:
以及某处,如果您没有这样做:
那么这将导致包装的
std::vector
满足 Python 的 MutableSequence。 (我认为这应该足以实现您在 Python 方面寻找的目标,您可能还需要使用-extranative
调用 SWIG)。另外值得注意的是 - 对于您当前的 __getitem__ ,您可以使用类似以下内容在 SWIG 接口文件中声明和定义它:
这允许您在不使用 SWIG+“污染”您的“正常”头文件的情况下执行此操作Python特定代码。
I think there's a much simpler solution to this for
std::vector
with SWIG+Python. SWIG's Python code generation already has support for doing quite a good job wrapping some STL containers.If you add to the beginning of your module interface:
and somewhere, if you haven't done so:
then this will cause the wrapped
std::vector
to meet the requirements of Python's MutableSequence. (I think this should be sufficient to achieve what you're looking for on the Python side, you might need to call SWIG with-extranative
as well).Also worth noting possibly - for your current
__getitem__
you can declare and define it in the SWIG interface file using something like:Which allows you to do this without "polluting" your "normal" header files with SWIG+Python specific code.