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 Web框架Flask信号机制(signals)介绍
Jan 01 Python
使用Python实现BT种子和磁力链接的相互转换
Nov 09 Python
python数据结构之链表详解
Sep 12 Python
Python实现字符串匹配的KMP算法
Apr 04 Python
Pycharm运行加载文本出现错误的解决方法
Jun 27 Python
python实现邮件发送功能
Aug 10 Python
python 字典的打印实现
Sep 26 Python
Python解析多帧dicom数据详解
Jan 13 Python
Python 实现向word(docx)中输出
Feb 13 Python
推荐8款常用的Python GUI图形界面开发框架
Feb 23 Python
Python爬虫后获取重定向url的两种方法
Jan 19 Python
编写python程序的90条建议
Apr 14 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/10/09 PHP
学习使用curl采集curl使用方法
2012/01/11 PHP
php按字符无乱码截取中文的方法
2015/03/27 PHP
PHP代码维护,重构变困难的4种原因分析
2016/01/25 PHP
utf8的编码算法 转载
2006/12/27 Javascript
Google的跟踪代码 动态加载js代码方法应用
2012/11/12 Javascript
JQuery入门—JQuery程序的代码风格详细介绍
2013/01/03 Javascript
javascript限制文本框只允许输入数字(曾经与现在的方法对比)
2013/01/18 Javascript
js 图片随机不定向浮动的实现代码
2013/07/02 Javascript
javascript学习笔记(六)数据类型和JSON格式
2014/10/08 Javascript
微信小程序 使用腾讯地图SDK详解及实现步骤
2017/02/28 Javascript
angular directive的简单使用总结
2017/05/24 Javascript
jQuery实现获取form表单内容及绑定数据到form表单操作分析
2018/07/03 jQuery
JS实现继承的几种常用方式示例
2019/06/22 Javascript
5分钟教你用nodeJS手写一个mock数据服务器的方法
2019/09/10 NodeJs
跟老齐学Python之用while来循环
2014/10/02 Python
Python的Flask框架标配模板引擎Jinja2的使用教程
2016/07/12 Python
python 出现SyntaxError: non-keyword arg after keyword arg错误解决办法
2017/02/14 Python
python 迭代器和iter()函数详解及实例
2017/03/21 Python
Python数据类型中的“冒号“[::]——分片与步长操作示例
2018/01/24 Python
python使用Tesseract库识别验证
2018/03/21 Python
Django实现文章详情页面跳转代码实例
2020/09/16 Python
django使用多个数据库的方法实例
2021/03/04 Python
使用CSS3制作版头动画效果
2020/12/24 HTML / CSS
基于HTML5+Webkit实现树叶飘落动画
2017/12/28 HTML / CSS
Html5获取高德地图定位天气的方法
2019/12/26 HTML / CSS
斯凯奇新西兰官网:SKECHERS新西兰
2018/02/22 全球购物
Bealls Florida百货商店:生活服饰、家居装饰和鞋子
2018/02/23 全球购物
eBay加拿大站:eBay.ca
2019/06/20 全球购物
人事助理岗位职责
2013/11/18 职场文书
教师实习自我鉴定
2013/12/13 职场文书
大学生在校学习的自我评价
2014/02/18 职场文书
后进基层党组织整改方案
2014/10/25 职场文书
先进党员事迹材料
2014/12/24 职场文书
Zabbix对Kafka topic积压数据监控的解决方案
2022/07/07 Servers
javascript进阶篇深拷贝实现的四种方式
2022/07/07 Javascript