Python中的yield浅析


Posted in Python onJune 16, 2014

在介绍yield前有必要先说明下Python中的迭代器(iterator)和生成器(constructor)。

一、迭代器(iterator)

在Python中,for循环可以用于Python中的任何类型,包括列表、元祖等等,实际上,for循环可用于任何“可迭代对象”,这其实就是迭代器

迭代器是一个实现了迭代器协议的对象,Python中的迭代器协议就是有next方法的对象会前进到下一结果,而在一系列结果的末尾是,则会引发StopIteration。任何这类的对象在Python中都可以用for循环或其他遍历工具迭代,迭代工具内部会在每次迭代时调用next方法,并且捕捉StopIteration异常来确定何时离开。

使用迭代器一个显而易见的好处就是:每次只从对象中读取一条数据,不会造成内存的过大开销。

比如要逐行读取一个文件的内容,利用readlines()方法,我们可以这么写:

for line in open("test.txt").readlines():
    print line

这样虽然可以工作,但不是最好的方法。因为他实际上是把文件一次加载到内存中,然后逐行打印。当文件很大时,这个方法的内存开销就很大了。

利用file的迭代器,我们可以这样写:

for line in open("test.txt"):   #use file iterators
    print line

这是最简单也是运行速度最快的写法,他并没显式的读取文件,而是利用迭代器每次读取下一行。

二、生成器(constructor)

生成器函数在Python中与迭代器协议的概念联系在一起。简而言之,包含yield语句的函数会被特地编译成生成器。当函数被调用时,他们返回一个生成器对象,这个对象支持迭代器接口。函数也许会有个return语句,但它的作用是用来yield产生值的。

不像一般的函数会生成值后退出,生成器函数在生成值后会自动挂起并暂停他们的执行和状态,他的本地变量将保存状态信息,这些信息在函数恢复时将再度有效

>>> def g(n):
...     for i in range(n):
...             yield i **2
...
>>> for i in g(5):
...     print i,":",
...
0 : 1 : 4 : 9 : 16 :

要了解他的运行原理,我们来用next方法看看:
>>> t = g(5)
>>> t.next()
0
>>> t.next()
1
>>> t.next()
4
>>> t.next()
9
>>> t.next()
16
>>> t.next()
Traceback (most recent call last):
  File "", line 1, in 
StopIteration

在运行完5次next之后,生成器抛出了一个StopIteration异常,迭代终止。
再来看一个yield的例子,用生成器生成一个Fibonacci数列:

def fab(max):
    a,b = 0,1
    while a < max:
        yield a
        a, b = b, a+b
>>> for i in fab(20):
...     print i,",",
...
0 , 1 , 1 , 2 , 3 , 5 , 8 , 13 ,

看到这里应该就能理解生成器那个很抽象的概念了吧~~
Python 相关文章推荐
跟老齐学Python之坑爹的字符编码
Sep 28 Python
python爬虫正则表达式之处理换行符
Jun 08 Python
Python图像的增强处理操作示例【基于ImageEnhance类】
Jan 03 Python
Python中的 enum 模块源码详析
Jan 09 Python
python三引号输出方法
Feb 27 Python
在django view中给form传入参数的例子
Jul 19 Python
如何使用Flask-Migrate拓展数据库表结构
Jul 24 Python
python求平均数、方差、中位数的例子
Aug 22 Python
Python爬虫实现“盗取”微信好友信息的方法分析
Sep 16 Python
python lambda表达式(匿名函数)写法解析
Sep 16 Python
Python使用Turtle库绘制一棵西兰花
Nov 23 Python
python requests模拟登陆github的实现方法
Dec 26 Python
python中使用enumerate函数遍历元素实例
Jun 16 #Python
Python中字典(dict)和列表(list)的排序方法实例
Jun 16 #Python
Python实现的几个常用排序算法实例
Jun 16 #Python
Python中文件遍历的两种方法
Jun 16 #Python
Python里隐藏的“禅”
Jun 16 #Python
Python程序设计入门(5)类的使用简介
Jun 16 #Python
Python程序设计入门(4)模块和包
Jun 16 #Python
You might like
?算你??的 PHP 程式大小
2006/12/06 PHP
php简单封装了一些常用JS操作
2007/02/25 PHP
php下防止单引号,双引号在接受页面转义的设置方法
2008/09/25 PHP
php连接mssql的一些相关经验及注意事项
2013/02/05 PHP
一个简单的php加密解密函数(动态加密)
2013/06/19 PHP
JavaScript函数、方法、对象代码
2008/10/29 Javascript
潜说js对象和数组
2011/05/25 Javascript
Tab页界面 用jQuery及Ajax技术实现(php后台)
2011/10/12 Javascript
javascript获取下拉列表框当中的文本值示例代码
2013/07/31 Javascript
用jquery写的菜单从左往右滑动出现
2014/04/11 Javascript
原生Js实现简易烟花爆炸效果的方法
2015/03/20 Javascript
JavaScript动态加载样式表的方法
2015/03/21 Javascript
详解JavaScript基本类型和引用类型
2015/12/09 Javascript
全屏js头像上传插件源码高清版
2016/03/29 Javascript
JavaScript Ajax编程 应用篇
2016/07/02 Javascript
JavaScript中this的四个绑定规则总结
2016/09/26 Javascript
js操作浏览器的参数方法
2017/01/21 Javascript
Vue.js之slot深度复制详解
2017/03/10 Javascript
jQuery remove()过滤被删除的元素(推荐)
2017/07/18 jQuery
js getBoundingClientRect使用方法详解
2019/07/17 Javascript
javascript实现商品图片放大镜
2019/11/28 Javascript
Vue事件处理原理及过程详解
2020/03/11 Javascript
Python标准库urllib2的一些使用细节总结
2015/03/16 Python
Python实现批量下载图片的方法
2015/07/08 Python
python实现excel读写数据
2021/03/02 Python
解决Python中list里的中文输出到html模板里的问题
2018/12/17 Python
对Python 多线程统计所有csv文件的行数方法详解
2019/02/12 Python
python把1变成01的步骤总结
2019/02/27 Python
python射线法判断一个点在图形区域内外
2019/06/28 Python
Python 导入文件过程图解
2019/10/15 Python
Django实现celery定时任务过程解析
2020/04/21 Python
金宝贝童装官网:Gymboree
2016/08/31 全球购物
廉价连衣裙和婚纱礼服在线销售:Tbdress
2019/02/28 全球购物
学历证明样本
2015/06/16 职场文书
sql注入报错之注入原理实例解析
2022/06/10 MySQL
windows10声卡驱动怎么安装?win10声卡驱动安装操作步骤教程
2022/08/05 数码科技