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

时间:2012-01-11 09:38:28

标签: python swig

我正在使用SWIG生成C扩展Python库。我有一个C数据类型,它本质上是一个序列类型,它(在概念上)映射到Python中的列表数据类型。

我已经使用SWIG生成了扩展,但是现在,想要改进SWIG接口以便使用库编写的代码更加Pythonic。

我在我的界面文件中使用%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 个答案:

答案 0 :(得分:1)

错误似乎在:

else:
   datasize = self.size()

错误表示您尚未定义名为size()的属性。

您是否考虑过在C ++中实现函数__getitem____setitem____len__,然后让它们暴露给Python?为此,您可以在SWIG中使用%extend指令。