使用SWIG的Python C扩展(通过%pythoncode关键字添加魔法方法)
我正在使用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
指令来达到这个目的。