使对象的C++数组在Python中可迭代
Make C++ array of objects iterable in Python
我在网上搜索过,但没有成功。我将下面的示例代码封装到Python中(使用SWIG):
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不能使用comands 迭代或访问lista
>>> 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
可迭代?有没有一种方法可以使用Python列表而不是C++数组?
我的Python版本是3.2,我使用的是带有g++4.6.1 的SWIG 2.0.4
感谢
从您的问题中可以看出,您是否想要使用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;
}
您可以用%template
、pyabc.i
和std_vector.i
包装它,例如:
%module test
%{
#include "test.h"
%}
%include "pyabc.i"
%include "std_vector.i"
%include "test.h"
%template (FooVector) std::vector<foo>;
其将在Python类型上直观地表现。你需要打电话给SWIG,告诉他们:
swig-python-c++-py3-外部测试.i
如果这个想法是包装一个"自定义"容器,以便在Python方面直观地表现,我在前面的回答中给出了一个详细的例子。
为了简单起见,您可能希望在Python端而不是C++/SWIG端解决此问题。
# 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)
类似于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文件应该更简单。
此外,SWIG有STL容器的包装器,所以也许使用这些包装器,您可以轻松地获得必要的项目getter。
相关文章:
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++中带有List类的迭代器Segfault
- 迭代时从向量和内存中删除对象
- 如何在c++迭代器类型中包装std::chrono
- 迭代从 SWIG 绑定返回的 python 中的 vector<pair<int,int>>
- python+libclang;来回迭代:将字段注释绑定到字段
- Python 对象不可迭代或下标
- 提升 python 容器、迭代器和项的生存期
- 为什么boost::python迭代器跳过第一个元素
- 如何制作更具表现力的 Python 迭代器?就像 C++ 迭代器一样
- 如何为python可迭代内容编写c++包装器
- 有效地使用python对象来迭代调用python函数的大型数据集
- 使对象的C++数组在Python中可迭代
- python和基类虚函数的迭代器
- 用Python生成器替换c++ STL输出迭代器
- 在索引和值"for i, v in enumerate(listVar):"上是否有 C++/C++11 类似于 python 迭代?
- Python中的递增迭代器(iter)
- GDB Python脚本:通过C/C++结构字段迭代的任何示例
- 在python中跳过for循环中的迭代