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益智游戏计算汉诺塔问题示例
Mar 05 Python
Python选择排序、冒泡排序、合并排序代码实例
Apr 10 Python
Python实现短网址ShortUrl的Hash运算实例讲解
Aug 10 Python
python中函数传参详解
Jul 03 Python
对python中的logger模块全面讲解
Apr 28 Python
详解pandas安装若干异常及解决方案总结
Jan 10 Python
python 将有序数组转换为二叉树的方法
Mar 26 Python
python多进程下实现日志记录按时间分割
Jul 22 Python
Python爬虫实现“盗取”微信好友信息的方法分析
Sep 16 Python
python 字典有序并写入json文件过程解析
Sep 30 Python
Django模板标签中url使用详解(url跳转到指定页面)
Mar 19 Python
使用python创建生成动态链接库dll的方法
May 09 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三元运算符的结合性介绍
2012/01/10 PHP
php对图像的各种处理函数代码小结
2013/07/08 PHP
jquery提示 &quot;object expected&quot;的解决方法
2009/12/13 Javascript
分享10篇优秀的jQuery幻灯片制作教程及应用案例
2011/04/16 Javascript
用Jquery重写windows.alert方法实现思路
2013/04/03 Javascript
为什么要在引入的css或者js文件后面加参数的详细讲解
2013/05/03 Javascript
浅析onsubmit校验表单时利用ajax的return false无效问题
2013/07/10 Javascript
JQuery动画animate的stop方法使用详解
2014/05/09 Javascript
jquery实现点击变换导航样式的方法
2015/08/31 Javascript
详解Angular.js指令中scope类型的几种特殊情况
2017/02/21 Javascript
Vue和Bootstrap的整合思路详解
2017/06/30 Javascript
实例讲解javascript实现异步图片上传方法
2017/12/05 Javascript
微信小程序数字滚动插件使用详解
2018/02/02 Javascript
jQuery 点击获取验证码按钮及倒计时功能
2018/09/20 jQuery
vue实现滚动鼠标滚轮切换页面
2020/12/13 Vue.js
[01:32]寻找你心中的那团火 DOTA2 TI9火焰传递活动今日开启
2019/05/16 DOTA
Django的信号机制详解
2017/05/05 Python
python matplotlib绘图,修改坐标轴刻度为文字的实例
2018/05/25 Python
python3爬取数据至mysql的方法
2018/06/26 Python
python调用百度地图WEB服务API获取地点对应坐标值
2019/01/16 Python
Python如何爬取微信公众号文章和评论(基于 Fiddler 抓包分析)
2019/06/28 Python
在python 中split()使用多符号分割的例子
2019/07/15 Python
tensor和numpy的互相转换的实现示例
2019/08/02 Python
基于DOM+CSS3实现OrgChart组织结构图插件
2016/03/02 HTML / CSS
汉语言文学职业规划
2014/02/14 职场文书
网络管理员岗位职责
2014/03/17 职场文书
房务中心文员岗位职责
2014/04/16 职场文书
乡镇镇长个人整改措施
2014/10/01 职场文书
警察群众路线对照检查材料思想汇报
2014/10/01 职场文书
法律讲堂观后感
2015/06/11 职场文书
海上钢琴师的观后感
2015/06/11 职场文书
乡镇团代会开幕词
2016/03/04 职场文书
使用javascript解析二维码的三种方式
2021/11/11 Javascript
Python os和os.path模块详情
2022/04/02 Python
Vue组件化(ref,props, mixin,.插件)详解
2022/05/15 Vue.js
Java 中的 Lambda List 转 Map 的多种方法详解
2022/07/07 Java/Android