2012-01-17 58 views
3

我在網上搜索過但沒有獲得成功。我包裝下面的示例代碼到Python(使用痛飲):在Python中製作可迭代的C++數組對象

class atomo { 
public: 
    int i; 
    atomo(int a) { 
     i = a; 
    };  
}; 

class funa { 
public: 
    atomo *lista[3]; 

    funa() { 
     lista[0] = new atomo(1); 
     lista[1] = new atomo(2); 
     lista[2] = new atomo(3); 
    }; 
}; 

但是Python不能超過迭代或使用該命令對應的

>>> test = myModule.funa() 
>>> test.lista[0] 
     Traceback (most recent call last): 
     File "<stdin>", line 1, in <module> 
     File "<stdin>", line 6, in __iter__ 
     TypeError: 'SwigPyObject' object is not subscriptable 

>>> for i in test.lista: 
>>>  print(i) 
     Traceback (most recent call last): 
     File "<stdin>", line 1, in <module> 
     File "<stdin>", line 6, in __iter__ 
     TypeError: 'SwigPyObject' object is not subscriptable 

訪問lista我怎樣才能讓lista迭代?有一種方法可以使用Python列表而不是C++數組?

我的Python版本是3.2,我使用痛飲2.0.4使用g ++ 4.6.1

感謝

+0

只是一個猜測:'名單(test.lista)' – rplnt 2012-01-17 15:09:27

回答

2

,如果你想使用std::vector或您自己的類型的數組這是從你的問題有點不清楚。

對於std::vector,給出了一些C++這樣的:

#include <vector> 
#include <string> 

struct foo { 
    std::string name; 
}; 

inline std::vector<foo> test() { 
    std::vector<foo> ret; 
    foo instance; 
    instance.name = "one"; 
    ret.push_back(instance); 
    instance.name = "two"; 
    ret.push_back(instance); 
    return ret; 
} 

您可以%templatepyabc.istd_vector.i例如爲:

%module test 

%{ 
#include "test.h" 
%} 

%include "pyabc.i" 
%include "std_vector.i" 

%include "test.h" 

%template (FooVector) std::vector<foo>; 

這將直觀地表現於Python類型的包裹。你需要調用痛飲的東西,如:

swig -python -c++ -py3 -extranative test.i

如果這個想法是包裝一個「自定義」容器直觀地表現對Python的身邊,我在前面的回答給了detailed example

1

你可能想解決這個在Python端,而不是C++ /痛飲側簡單。

# wrapper/facade 
class Funa: 
    def __init__(self): 
     self._impl = myModule.funa() # _impl => implementation 

    def __iter__(self): 
     for i in xrange(3): 
      yield self._impl.lista[i] 

test = Funa() 
for x in test: 
    print(x) 
+0

@ user1154091:只要你保持在Python內部循環,你不會得到太多的速度。將內部循環移到C++代碼中,真正發揮作用。 – 2012-01-17 15:20:03

+0

@Sven Marnach:這只是顯示相同錯誤的一段簡單代碼。我真正的代碼的瓶頸是類'atomo' – 2012-01-17 15:30:09

+0

@CaioS的instanciation:我的意見是上述響應你的(現已刪除)評論說,你不喜歡這個答案,因爲它可能是太慢了。 – 2012-01-17 15:41:43

0

larsmans類似的方法是讓Funa.__iter__返回一個生成器對象。那麼你只需要添加到SWIG創建的接口。 (在他的包裝,你就必須包裝所有其他方法,或用__getattr__玩。)大致會是這樣

class Funa: 

    class FunaIter : 
    def __init__(self, parent) : 
     self.parent = parent 
     self.pos = 0 

    def __iter__(self) : 
     while self.pos < 3 : 
     yield self.parent.lista[self.pos] 
     self.pos += 1 

    def __iter__(self) : 
    return self.FunaIter(self) 

這應該是簡單的插入使用%extend%pythoncode指令你痛飲文件。

此外,SWIG has wrappers for STL containers,所以也許使用這些,你可以很容易地獲得必要的項目干將。