Python 生成器学习
2014-05-06 16:32
260 查看
原文地址:http://www.cnblogs.com/huxi/archive/2011/07/14/2106863.html
4. 生成器(generator)
4.1. 生成器简介
首先请确信,生成器就是一种迭代器。生成器拥有next方法并且行为与迭代器完全相同,这意味着生成器也可以用于Python的for循环中。另外,对于生成器的特殊语法支持使得编写一个生成器比自定义一个常规的迭代器要简单不少,所以生成器也是最常用到的特性之一。
从Python 2.5开始,[PEP 342:通过增强生成器实现协同程序]的实现为生成器加入了更多的特性,这意味着生成器还可以完成更多的工作。这部分我们会在稍后的部分介绍。
4.2. 生成器函数
4.2.1. 使用生成器函数定义生成器
如何获取一个生成器?首先来看一小段代码:
调用生成器函数将返回一个生成器;
我们的小例子中并没有用到变量,所以这里另外定义一个生成器来展示这个特点:
4.2.2. 生成器函数的FAQ
接下来我们来讨论一些关于生成器的有意思的话题。
你的例子里生成器函数都没有参数,那么生成器函数可以带参数吗?
当然可以啊亲,而且它支持函数的所有参数形式。要知道生成器函数也是函数的一种:)
既然生成器函数也是函数,那么它可以使用return输出返回值吗?
不行的亲,是这样的,生成器函数已经有默认的返回值——生成器了,你不能再另外给一个返回值;对,即使是return None也不行。但是它可以使用空的return语句结束。如果你坚持要为它指定返回值,那么Python将在定义的位置赠送一个语法错误异常,就像这样:
Python会在真正离开try...finally时再执行finally中的代码,而这里遗憾地告诉你,暂停不算哦!所以结局你也能猜到吧!
*另外,“在带有finally子句的try块中yield”定义在PEP 342中,这意味着只有Python 2.5以上版本才支持这个语法,在Python 2.4以下版本中会得到语法错误异常。
如果我需要在生成器的迭代过程中接入另一个生成器的迭代怎么办?写成下面这样好傻好天真。。
有更多问题?请回复此文:)
4.3. 协同程序(coroutine)
协同程序(协程)一般来说是指这样的函数:
彼此间有不同的局部变量、指令指针,但仍共享全局变量;
可以方便地挂起、恢复,并且有多个入口点和出口点;
多个协同程序间表现为协作运行,如A的运行过程中需要B的结果才能继续执行。
协程的特点决定了同一时刻只能有一个协同程序正在运行(忽略多线程的情况)。得益于此,协程间可以直接传递对象而不需要考虑资源锁、或是直接唤醒其他协程而不需要主动休眠,就像是内置了锁的线程。在符合协程特点的应用场景,使用协程无疑比使用线程要更方便。
从另一方面说,协程无法并发其实也将它的应用场景限制在了一个很狭窄的范围,这个特点使得协程更多的被拿来与常规函数进行比较,而不是与线程。当然,线程比协程复杂许多,功能也更强大,所以我建议大家牢牢地掌握线程即可:Python线程指南
这一节里我也就不列举关于协程的例子了,以下介绍的方法了解即可。
Python 2.5对生成器的增强实现了协程的其他特点,在这个版本中,生成器加入了如下方法:
send(value):
send是除next外另一个恢复生成器的方法。Python 2.5中,yield语句变成了yield表达式,这意味着yield现在可以有一个值,而这个值就是在生成器的send方法被调用从而恢复执行时,调用send方法的参数。
*如果使用next恢复生成器,yield表达式的值将是None。
close():
这个方法用于关闭生成器。对关闭的生成器后再次调用next或send将抛出StopIteration异常。
throw(type, value=None, traceback=None):
这个方法用于在生成器内部(生成器的当前挂起处,或未启动时在定义处)抛出一个异常。
*别为没见到协程的例子遗憾,协程最常见的用处其实就是生成器。
4.4. 一个有趣的库:pipe
这一节里我要向诸位简要介绍pipe。pipe并不是Python内置的库,如果你安装了easy_install,直接可以安装它,否则你需要自己下载它:http://pypi.python.org/pypi/pipe
之所以要介绍这个库,是因为它向我们展示了一种很有新意的使用迭代器和生成器的方式:流。pipe将可迭代的数据看成是流,类似于linux,pipe使用'|'传递数据流,并且定义了一系列的“流处理”函数用于接受并处理数据流,并最终再次输出数据流或者是将数据流归纳得到一个结果。我们来看一些例子。
第一个,非常简单的,使用add求和:
pipe实现起来非常简单,使用Pipe装饰器,将普通的生成器函数(或者返回迭代器的函数)代理在一个实现了__ror__方法的普通类实例上即可,但是这种思路真的很有趣。
相关文章推荐
- python学习笔记4.1-python高级之生成器
- python学习——生成器
- Python学习之迭代对象、迭代器、生成器
- <python全栈开发基础>学习过程笔记【17d】生成器
- Python学习笔记——生成器,yeild语句
- python学习-面向对象进阶之生成器(十一)
- Python3 学习第六弹: 迭代器与生成器
- Python学习4:生成器、lamda表达式及map、reduce、filter函数
- yield生成器对象返回Fiabs元素 分类: python 小练习 python基础学习 2014-01-13 10:28 193人阅读 评论(0) 收藏
- Python学习笔记2:构造序列:列表推导和生成器表达式
- 流畅的python第十四章可迭代的对象,迭代器和生成器学习记录
- python学习之路4------列表生成器
- python学习19--生成器
- Python学习:列表生成式和列表生成器
- python中的生成器(generator) 分类: python Module python基础学习 2013-10-28 17:41 310人阅读 评论(0) 收藏
- Python高级特性(切片 迭代 列表生成式 生成器 迭代器)学习笔记
- 08-python学习笔记-生成器:generator
- python学习之路4------列表生成器
- Python学习笔记——生成器
- Python进阶篇学习笔记一:异常机制、属性和生成器