龙空技术网

Python扩展C/C++开发:实现生成器和迭代器

编程开发指南 170

前言:

今天你们对“c迭代器”大约比较讲究,姐妹们都需要了解一些“c迭代器”的相关知识。那么小编在网上网罗了一些有关“c迭代器””的相关内容,希望兄弟们能喜欢,大家一起来了解一下吧!

生成器和迭代器是相互依赖的,迭代器每次需要一个值,调用生成器返回一直,直到生成器返回集合所有的值。这个过程是交替执行的。

迭代器

迭代器是一个可以记住遍历的位置的对象。从集合的第一个元素开始遍历,直至集合所有的元素都被访问完毕。

接下来会使用C/C++实现迭代器的遍历,用C/C++实现一个传参为迭代器对象的函数,内部会先调用 PyObject_GetIter 将对象转化为一个可迭代的对象,然后循环调用 PyIter_Next,直至返回NULL,在遍历的过程中调用 PyObject_Print 输出集合元素,并减少 item 的引用次数,最后通过 Py_BuildValue 构建一个空的返回值。

C/C++ 实现,实现迭代器编写 setup.py 安装动态链接库,分发模块

执行 python setup.py install 将动态链接库生出,并拷贝至系统模块中,方便程序导入调用

编写Python程序,测试结果

如下程序执行 python test.py 可以看到输出结果为 0 \~ 19 的整数,证明我们的程序是正确的。

生成器

生成器是特殊的子程序,类似返回数组的函数,具备参数,可以被调用,产生一些列的值,但是所有的值不是一次性返回,每次产生一个值。

编写 C/C++ 代码,实现生成器

如下程序是实现一个反转列表的生成器,倒序输出列表中的值。生成器是一个类。

生成器相对于迭代器略微复杂,首先我们需要自定义一个类 RevgenState,与之前的C/C++实现扩展类原理相似,中间多了一个环节就是实现 next 的调用过程 revgen_next。

首先程序需要判断游标是否已经遍历完所有的元素,如果遍历结束返回空 NULL。否则返回对应索引的值,并移动索引。PySequence_GetItem 第一个参数为列表,第二个参数为索引,帮助我们快速检索元素,程序拿到返回值返回给外部。

编写测试程序,测试生成器和迭代器

执行如下程序python test.py, 输出结果一次为(0, 'c'), (1, 'b'), (2, 'a')。从结果来看已经达到了此次实验的目的。

总结

从以上实验的过程和结果来看,C/C++实现生成器和迭代器并没有想象的那么复杂,套用模板即可。了解C/C++开发Python扩展的整个流程之后,照搬模板就显得游刃有余了,简单点的参数调试和测试也十分的简单。

迭代器和生成器的出现可以避免一次性将数据加载到内存中,减少内存分配,腾出更多的内存空间给其他的模块。

标签: #c迭代器