使用SWIG的Python C扩展(通过%pythoncode关键字添加魔法方法)

3 投票
1 回答
858 浏览
提问于 2025-04-17 09:59

我正在使用SWIG来生成一个C语言扩展的Python库。我有一个C语言的数据类型,基本上是一个序列类型,概念上可以对应到Python中的列表类型。

我已经用SWIG生成了这个扩展,但现在我想改善SWIG的接口,让使用这个库的代码看起来更像Python代码。

我在我的接口文件中使用了%pythoncode关键字,以便添加一些Python的魔法函数,比如__getitem__等。

以下是我SWIG接口文件中相关的部分:

%pythoncode %{
    def __getitem__(self, key):
        if not isinstance(key, int ):
            raise TypeError('Index value must be integer')
        else:
            datasize = self.size()
            if (key > -1) and (key < datasize):
                return self.getItem(key)
            else:
                raise IndexError('Index out of array bounds')

    def __setitem__(self, key, value):
        if not isinstance(key, int ):
            raise TypeError('Index value must be integer')
        else:
            if not isinstance(value, double) and not isinstance(value, int):
                raise TypeError('Value must be a number')
            else:
                datasize = self.size()
                if (key > -1) and (key < datasize):
                    return self.setItem(key, value)
                else:
                    raise IndexError('Index out of array bounds')


    def __iter__(self):
        return self

    def next(iterator):
        raise StopIteration()
%}

我编译后成功在Python中导入了这个库。

import mylib
temp = mylib.MySequenceDataType(10)
temp[0] = 42

但是,当我尝试像上面那样给我的序列数据类型赋值时,出现了以下错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "myextlib.py", line 195, in __getitem__
    datasize = self.size()
  File "myextlib.py", line 151, in <lambda>
    __getattr__ = lambda self, name: _swig_getattr(self, MySequenceDataType, name)
  File "myextlib.py", line 55, in _swig_getattr
    raise AttributeError(name)
AttributeError: size

我该如何解决这个问题呢?那些眼尖的人可能也会注意到,我目前的迭代实现是无法工作的。我也希望能得到一些关于如何让它正常工作的建议或帮助。

1 个回答

1

错误似乎出现在:

else:
   datasize = self.size()

这个错误提示你没有定义一个叫做 size() 的属性。

你有没有考虑过在C++中实现 __getitem____setitem____len__ 这些函数,然后让它们可以在Python中使用?你可以在SWIG中使用 %extend 指令来达到这个目的。

撰写回答