作者:灰衣人
Py 2.5 what's new 之 yield
Date: 2006-8-31
Author: shhgs
Copyright: 为了表达本人对CSDN论坛“脚本语言(Perl/Python)”专区的强烈不满,特此宣布,本文档不允许任何人发布或者链接到CSDN论坛的“脚本语言Perl/Python”专区。除此之外,任何人均可以阅读,分发本文档的电子版,或者本文档的链接。此外,任何人均可以将本文档张贴到除CSDN论坛“脚本语言Perl/Python”专区之外的其它 BBS。任何人均可以打印本文档,以供自己或他人使用,但是不得以任何名义向任何人收取任何费用。上述名义包括,但不限于,纸张费,打印费,耗材费等等。分发、张贴本文档的时候,必须保留这段版权申明。如果有人要出版本文档,必须事先获得本人的同意。
Py 2.5 对yield做了本质性的增强,使得Py有了自己的first class的coroutine。
我们先来看看传统的yield。Py 2.3加入的yield使得Python实现了first class的generator。 generator是enumerator/iterator的自然延伸,其区别在于,iterator/enumerator遍历的是一个既有的有限集合,而generator则是依次生成集合的各个元素,并且这个集合还可以是无限的。从算法上讲,generator同递归一样,源出数学归纳法,但是与递归相比,一是其代码更为清晰,二是它没有嵌套层数的限制。
但是你提供工具想让别人干什么和别人会怎么去用这个工具,从根本上讲是两码事。generator 问世之初就有人敏感地指出,这是一个semi coroutine。所谓的coroutine是指,一种有多个 entry point和suspend point的routine。Py 2.3的yield实现了多个entry/suspend point,但是由于其无法在generator每次重新启动的时候往里面传新的数据,因此只能被称作semi coroutine。
当然也不是全然没有办法。但是总的来说,要想往里面传新的数据,你就得动用一些技巧。本文的主旨不在于向诸位介绍这些技巧,这里我们关心的是,为什么那些大牛们要挖空心思去改造generator,他们想要干什么,以及怎么干。
Py 2.5 yield 的语法
讲了半天往generator里面传数据,那么怎么个传法呢?
Py 2.5的generator有了一个新的send方法,我们就是用这个send往里面传数据。:
gen.send(message)
那么generator又是怎样接收数据的呢?这里,Py 2.5对yield的语法做了改造。现在yield已经不是一个语句了,而是一个表达式。因此当你:
val = yield i
传给generator的值就被赋予val了,而generator还是像以前那样生成i。
现在:
gen.next()
成了:
gen.send(None)
的简写,而:
yield i
则表示generator会忽略传进来的值。
yield的语法就这么简单,如果读者还有什么疑问的话,可以参看Python Manual里面的what's new。
yield的用途
1. 合作多任务
PEP342 提到的coroutine的用途包括“模拟,游戏,异步I/O,以及其它形式的事件驱动或合作多任务编程”。那么我们就从相对简单的合作多任务开始。
所谓合作多任务的意思是,一个系统同时有多个任务在运行,而且这些任务都非常的合作,会自愿地将系统的控制权转交给其它任务。与多线程相比,合作多任务有两个非常显著的特点。首先是顺序的决定性。大家都知道多线程环境是非决定性的。各个线程什么时候开始,什么时候挂起都是由线程调度机制决定的,因此你永远也无法知道某个线程会在什么时候挂起,什么时候重新启动。而合作多任务从本质上讲还是单线程的程序。只不过我们将每个任务封装成一个单独的函数 (这里就是generator),然后通过调度程序按照一定的算法轮流调用这种函数,从而推进任务的进展。
| 论坛热门帖子: | [lch203] 写得蛮好的linux学习笔记(10-21) [黑马制造] 学习java的30个目标(10-19) [笑傲股林] 做测试半年了,有点迷茫,应该再学些什么提高自己的测试水平和测试能力呢?(10-19) [udp8589] 大家用google的来吱一声? 用百度的~~也来报道下?(10-18) [沂偌掳兆] 本人总结的一些认为C++比较经典的书籍,希望对大家有用(10-18) |
| TAG标签: | generator 任务 一个 yield 合作 可以 coroutine 我们 |
注册
个人空间
