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中字典和JSON互转操作实例
Jan 19 Python
python基于pygame实现响应游戏中事件的方法(附源码)
Nov 11 Python
Django objects.all()、objects.get()与objects.filter()之间的区别介绍
Jun 12 Python
Python批处理删除和重命名文件夹的实例
Jul 11 Python
python+splinter自动刷新抢票功能
Sep 25 Python
在Pycharm中设置默认自动换行的方法
Jan 16 Python
浅谈python函数调用返回两个或多个变量的方法
Jan 23 Python
详解Python二维数组与三维数组切片的方法
Jul 18 Python
Python partial函数原理及用法解析
Dec 11 Python
Python requests模块安装及使用教程图解
Jun 30 Python
Python爬取股票信息,并可视化数据的示例
Sep 26 Python
Python基础知识学习之类的继承
May 31 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数组函数序列之array_splice() - 在数组任意位置插入元素
2011/11/07 PHP
PHP的MVC模式实现原理分析(一相简单的MVC框架范例)
2014/04/29 PHP
php自动获取关键字的方法
2015/01/06 PHP
php实现mysql数据库连接操作及用户管理
2015/11/08 PHP
PHP守护进程化在C和PHP环境下的实现
2017/11/21 PHP
JavaScript ( (__ = !$ + $)[+$] + ({} + $)[_/_] +({} + $)[_/_] )
2011/02/25 Javascript
jquery radio 操作代码
2011/03/16 Javascript
鼠标经过子元素触发mouseout,mouseover事件的解决方案
2015/07/26 Javascript
js验证框架之RealyEasy验证详解
2016/06/08 Javascript
深入学习nodejs中的async模块的使用方法
2017/07/12 NodeJs
详解使用angular的HttpClient搭配rxjs
2017/09/01 Javascript
Vue.js 实现微信公众号菜单编辑器功能(一)
2018/05/08 Javascript
nodejs通过钉钉群机器人推送消息的实现代码
2019/05/05 NodeJs
利用JavaScript为句子加标题的3种方法示例
2021/01/05 Javascript
[04:45]上海特级锦标赛主赛事第三日TOP10
2016/03/05 DOTA
Python使用Socket(Https)Post登录百度的实现代码
2012/05/18 Python
python中print()函数的“,”与java中System.out.print()函数中的“+”功能详解
2017/11/24 Python
Python分支结构(switch)操作简介
2018/01/17 Python
python占位符输入方式实例
2019/05/27 Python
Python对接六大主流数据库(只需三步)
2019/07/31 Python
Pycharm生成可执行文件.exe的实现方法
2020/06/02 Python
用React加CSS3实现微信拆红包动画效果
2017/03/13 HTML / CSS
Html5中的桌面通知Notification的实现
2018/09/25 HTML / CSS
雅诗兰黛美国官网:Estee Lauder美国
2016/07/21 全球购物
adidas菲律宾官网:adidas PH
2020/02/07 全球购物
考博自荐信
2013/10/25 职场文书
城管执法人员纪律作风整顿思想汇报
2014/09/13 职场文书
2014党员四风对照检查材料思想汇报
2014/09/17 职场文书
计生办班子群众路线教育实践活动个人对照检查材料思想汇报
2014/10/04 职场文书
公路局群众路线教育实践活动第一阶段工作汇报
2014/10/25 职场文书
学前班语言教学计划
2015/01/20 职场文书
房屋租赁意向书范本
2015/05/09 职场文书
学校中层领导培训心得体会
2016/01/11 职场文书
三年级作文之趣事作文
2019/11/04 职场文书
Python pandas读取CSV文件的注意事项(适合新手)
2021/06/20 Python
Redis分布式锁的7种实现
2022/04/01 Redis