Python Iterator Generators Yield 原理剖析及在Rasa框架源码中运用解析

Python Iterator Generators Yield 原理剖析及在Rasa框架源码中运用解析,第1张

一、Iterator、generator在Rasa源码中的运用

在Rasa框架源码中,可以看到关于Python的Iterator,Generator等的应用场景,熟练掌握这方面的知识对于深入理解源码是有帮助的。譬如下面关于form代码中的这个for循环其背后就是运用了iterator:

Generator某种程度上可以看做是对yield的封装,而yield从某种程度上来说可以看做是对iterator的改进。再来看下关于Rasa tracker store源码中的运用示例:

二、Iterator、generator原理解析

在使用list或者dict等类型进行循环取数 *** 作时就会使用到iterator,下面是关于generator,iterator相互作用关系的一个图。从图中可以看到,generator的背后是iterator,而iterator会实现接口Iterable,其核心逻辑就是通过next()方法逐个读取数据源中的元素,注意看右边描述的”lazily produce next value”,假设一个数据文件很大,内存不能一次加载完,那么采用这种方式就可以实现按需加载的方式。

(引用自Iterables vs. Iterators vs. Generators » nvie.com)

一个iterator就是实现了iterator protocol的对象,而iterator protocol是Python中的一个具有__next()__方法的特定类。这就意味着在每次当你请求下一个值时,一个iterator知道如何计算出这个值。Iterator会维护当前正在工作的iterable的状态信息(所谓状态,就是当你向iterator请求下一个值时,iterator能够根据状态知道当前元素和下一个元素是什么)。当你调用next()方法时,iterator就会取出下一个值。一个使用__next()__方法的对象就称之为iterator。如下图所示:

在这幅图中,你可以认为x是一个list(可进行迭代的对象),通过调用方法iter()来返回一个iterator对象。接下来调用next()方法来返回list中的一个元素,可以看到最后一个元素的值是3,遍历完元素之后要么抛出异常,要么就是提示已经到达遍历终点,这就看你具体如何设计了。只要你的数据对象实现了iterator protocol,就可以对里面的数据元素进行迭代处理从而获取其中的元素的值。在前面提到的懒加载机制(lazily produce next value)就是基于iterator能够维护iterable工作状态来实现的。

三、Python中实现Iterator protocol的对象介绍

Iterators能够帮助我们生成看起来更加清爽的代码,这是因为允许我们工作于无限的数据序列而不必为每一个可能的序列重新分配资源(这里的潜台词是无论你想要迭代的数据源有多大都没有关系,理论上iterator一般只关注当前的元素和下一个要迭代的元素),因此可以节省资源空间。Python有几个内置对象实现了iterator protocol,譬如lists,tuples,strings,dictionaries,甚至包括files(一般如果是读取大容量的文件而不会造成内存溢出的情况,往往是使用了iterator这样的机制)。在Python中存在很多iterators,所有itertools函数都返回iterators。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/715620.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-25
下一篇 2022-04-25

发表评论

登录后才能评论

评论列表(0条)

保存