如何使用SWIG从Python使C类可迭代?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了如何使用SWIG从Python使C类可迭代?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3498字,纯文字阅读大概需要5分钟。
内容图文
![如何使用SWIG从Python使C类可迭代?](/upload/InfoBanner/zyjiaocheng/664/bb687692c874414999f05bd49a717887.jpg)
我有一个管理std :: vector< Element> (班级的私人成员).
从C语言中,我可以使用begin()和end()迭代器(它们只是向量的迭代器的typedef)来遍历向量:
Collection col;
for (Collection::const_iterator itr = col.begin(); itr != col.end(); itr++)
{
std::cout << itr->get() << std::endl;
}
现在,我希望从Python做类似的事情:
import example
el = example.Element()
el.set(5)
col = example.Collection()
col.add(el)
for e in col:
print e.get()
但这导致:
TypeError: ‘Collection’ object is not iterable
我无法以为Python Collection类生成__iter__(我认为这是唯一需要)的方式配置SWIG.我应该怎么做?
这是我的代码:
example.h:
#include <vector>
class Element
{
public:
Element();
~Element();
int get() const;
void set(const int var);
private:
int variable_;
};
class Collection
{
public:
Collection();
~Collection();
void add(const Element& element);
typedef std::vector<Element> tElements;
// iterators
typedef tElements::iterator iterator;
typedef tElements::const_iterator const_iterator;
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
private:
tElements elements_;
};
example.cpp:
#include "example.h"
Element::Element() {}
Element::~Element() {}
int Element::get() const
{
return variable_;
}
void Element::set(const int var)
{
variable_ = var;
}
Collection::Collection() : elements_() {}
Collection::~Collection() {}
void Collection::add(const Element& element)
{
elements_.push_back(element);
}
Collection::iterator Collection::begin()
{
return elements_.begin();
}
Collection::const_iterator Collection::begin() const
{
return elements_.begin();
}
Collection::iterator Collection::end()
{
return elements_.end();
}
Collection::const_iterator Collection::end() const
{
return elements_.end();
}
example.i:
%module example
%{
#include "example.h"
%}
// I've tried to add this, but that generates a whole
// other class, that is not what I want.
// %include "std_vector.i"
// %template(ElementVector) std::vector<Element>;
// I've also tried to %extend the class (which I think is what I want,
// but I cannot figure out with what to extend it with)
// Include the header file with above prototypes
%include "example.h"
编译:
swig -python -c++ -o example_wrap.cpp example.i
g++ -fPIC -c example.cpp example_wrap.cpp -I/usr/include/python2.6
g++ -shared example.o example_wrap.o -o _example.so
解决方法:
受到最后一个示例的启发:https://stackoverflow.com/a/8828454/3613373.我想出了一种略有不同的方法,该方法不使用变量来检查StopIterator异常状态.
而且,它仅使用Collection的begin()end end()迭代器,而无需公开(公开)std :: vector< Element>.本身.
example.i:
%module example
%{
#include "example.h"
%}
%inline %{
class StopIterator {};
class Iterator {
public:
Iterator(Collection::iterator _cur, Collection::iterator _end) : cur(_cur), end(_end) {}
Iterator* __iter__()
{
return this;
}
Collection::iterator cur;
Collection::iterator end;
};
%}
%include "example.h"
%include "exception.i"
%exception Iterator::next {
try
{
$action // calls %extend function next() below
}
catch (StopIterator)
{
PyErr_SetString(PyExc_StopIteration, "End of iterator");
return NULL;
}
}
%extend Iterator
{
Element& next()
{
if ($self->cur != $self->end)
{
// dereference the iterator and return reference to the object,
// after that it increments the iterator
return *$self->cur++;
}
throw StopIterator();
}
}
%extend Collection {
Iterator __iter__()
{
// return a constructed Iterator object
return Iterator($self->begin(), $self->end());
}
};
我唯一不知道的事情是如何以仅可以传递任何Iterator< Collection,Element>的方式创建Iterator的模板版本.无需为每个模板实例重新定义next().欢迎解决方案;)
内容总结
以上是互联网集市为您收集整理的如何使用SWIG从Python使C类可迭代?全部内容,希望文章能够帮你解决如何使用SWIG从Python使C类可迭代?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。