Python yield 官方详解(基于2.x)


参考资料:Python yield 使用浅析


由于最近频繁的使用yield ,也就是Python中的Generators概念. 查看了Python的官方文档关于yield的使用,但是官方文档没有比较详细的介绍yield,只是简单介绍Generator时,使用了一个函数来使用yield举例。不够解渴呀。参考的文章个人感觉挺好,讲解了yield的使用目的,性能分析,内部基本实现,所以mark下来,一方面可以给大家看看,另一方面自己也可以经常学习。

*******************************

为了加深理解,结合对参考资料的理解和官方文档来逐步浅析生成器。

看看官方文档定义:

Generators are a simple and powerful tool for creating iterators. They are written like regular functions but use the
yield statement whenever they want to return data. Each time next() is called on it, the generator resumes where
it left off (it remembers all the data values and which statement was last executed). An example shows that generators
can be trivially easy to create:
def reverse(data):
for index in range(len(data)-1, -1, -1):
yield data[index]
>>> for char in reverse('golf'):
... print char
...
f
l
o
g

大概意思: 生成器是用于创建迭代对象的一个既简单,功能又强大的工具。生成器可以像普通的函数那样定义,但是与函数不同之处在于,在生成器中,无论何时想返回数据时,都可以通过yield来实现。每次返回的数据部都是通过调用next() 方法来得到的。当结束yield调用,得到返回的数据之后,程序流程又会继续执行上次调用yield之后的代码段,(就像中断一样,中断现场会被保护,会有程序计数器保存中断点信息,供返回时候调用)。

所以可以知道,上面那个例子的返回数据实质上是通过next() 得到的:

>>> def reverse(data):
...     for index in range(len(data)-1,-1,-1):
...         yield data[index]
... 
>>> results = reverse('golf')
>>> results.next()
'f'
>>> results.next()
'l'
>>> results.next()
'o'
>>> results.next()
'g'

可以查看返回值类型:

>>> type(results.next)
<type 'method-wrapper'>
>>> type(results)
<type 'generator'>

查看与迭代类型关系:

>>> isinstance(results.next(),Iterable)
True
>>> isinstance(results,Iterable)
True
可以知道返回值是属于迭代类型的,是可以迭代的,具有迭代类型特性。

看看官方对上述方法的详细解说:

Anything that can be done with generators can also be done with class-based iterators as described in the previous
section. What makes generators so compact is that the __iter__() and next() methods are created automatically.
Another key feature is that the local variables and execution state are automatically saved between calls. This made
the function easier to write and much more clear than an approach using instance variables like self.index and
self.data.
In addition to automatic method creation and saving program state, when generators terminate, they automatically
raise StopIteration. In combination, these features make it easy to create iterators with no more effort than
writing a regular function.


任何可以用Generators实现的同样也可以用类迭代器来实现。实质上生成器可以被如此简洁简单使用的原因是:通过yield返回的迭代对象会自动创建__iter__() 和next() 方法。(可以从面向对象的思想来考虑,同一类型的实体都可以用抽象的类来描述,可迭代的对象也可以用高度抽象的迭代类来描述,抽取出基本特征包括包含__iter__() 和next() 方法等等,可以参照官方关于迭代部分内容)

关于生成器功能实现的简洁性,另一个重要的特性是:本地变量和程序的执行状态在调用yield时,都会被自动保存(类似中断现场保护)。由于这个特性或者说机制,可以使得通过使用生成器可以写出比使用实例变量self.index 、self.data来实现相同的功能,更简洁,更清晰。(基于上面的方法分析)


生成器除了自动创建__iter__、next()方法和保存程序状态之外,当程序执行生成器结束之后,生成器会自动抛出StopIteration异常(表明已经没有数据可以迭代取出),综合以上这些特性,使得通过生成器创建迭代对象会比通过普通函数创建同样的迭代对象更轻松,方便。


*******************************************

其实,当没有用到yield或者使用yield时的匆匆一瞥,效果都是差不多的。只有自己亲身根据情景需要,结合yield特性使用时候,才是自己学到了。每天积累一点点零碎的知识点,坚持下去,老夫相信,总会进步的。若有错误之处,望同志们不吝指出。

英文翻译有点烂呀,希望大家谅解哦。嘿嘿


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值