2012-01-11 67 views
2

我正在使用SWIG生成C擴展Python庫。我有一個C數據類型,它本質上是一個序列類型,它在概念上映射到Python中的列表數據類型。使用SWIG的Python C擴展(使用%pythoncode關鍵字添加魔術方法)

我已經使用SWIG生成了擴展,但現在想要改進SWIG接口,以便使用庫編寫的代碼更加Python化。

我用我的接口文件中的%Python代碼的關鍵字,以添加像__ 的GetItem __

這是我痛飲接口文件的相關章節一些Python神奇功能:

%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 

我該如何解決這個問題?那些銳利的眼睛也會發現我目前的迭代實現不起作用。我會感謝指針/幫助geting,以及工作。

+1

'_swig_getattr'中引發的'AttributeError'表明您試圖訪問未包裝或名稱中有拼寫錯誤的成員。由於目前我們無法在問題中看到代碼中的部分內容,因此無法多說。你能產生一個*最小*但可能是完整的例子嗎?即您可以生成的最短的.i,.h和.c文件顯示問題? – Flexo 2012-01-12 11:47:00

回答

1

的錯誤似乎是:

else: 
    datasize = self.size() 

的錯誤表明您還沒有定義命名size()的屬性。

您是否考慮過在C++中實現函數__getitem__,__setitem____len__然後讓它們暴露給Python?爲此,您可以在SWIG中使用%extend指令。