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找出list中最常出现元素的方法
Jun 14 Python
python编程实现希尔排序
Apr 13 Python
Python序列化基础知识(json/pickle)
Oct 19 Python
python3.5 tkinter实现页面跳转
Jan 30 Python
python自动化报告的输出用例详解
May 30 Python
django自定义模板标签过程解析
Dec 14 Python
jupyter notebook 多环境conda kernel配置方式
Apr 10 Python
Django中使用Json返回数据的实现方法
Jun 03 Python
详解如何在pyqt中通过OpenCV实现对窗口的透视变换
Sep 20 Python
详解查看Python解释器路径的两种方式
Oct 15 Python
Django正则URL匹配实现流程解析
Nov 13 Python
Python 求向量的余弦值操作
Mar 04 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支持页面回退的两种方法
2008/01/10 PHP
PHP+MYSQL会员系统的登陆即权限判断实现代码
2011/09/23 PHP
PHP基于imagick扩展实现合成图片的两种方法【附imagick扩展下载】
2017/11/14 PHP
为何说PHP引用是个坑,要慎用
2018/04/02 PHP
Laravel定时任务的每秒执行代码
2019/10/22 PHP
锋利的jQuery jQuery中的DOM操作
2010/03/21 Javascript
js判断鼠标同时离开两个div的思路及代码
2013/05/31 Javascript
jQuery常用知识点总结以及平时封装常用函数
2016/02/23 Javascript
bootstrap table小案例
2016/10/21 Javascript
jQuery插件fullPage.js实现全屏滚动效果
2016/12/02 Javascript
jQuery窗口拖动功能的实现代码
2017/02/04 Javascript
详解jquery选择器的原理
2017/08/01 jQuery
Vue cli构建及项目打包以及出现的问题解决
2018/08/27 Javascript
vue 界面刷新数据被清除 localStorage的使用详解
2018/09/16 Javascript
vue-cli3配置与跨域处理方法
2019/08/17 Javascript
原生js实现日期选择插件
2020/05/21 Javascript
JS+CSS实现炫酷光感效果
2020/09/05 Javascript
[02:32]DOTA2亚洲邀请赛 VG战队巡礼
2015/02/03 DOTA
python获取从命令行输入数字的方法
2015/04/29 Python
Python双向循环链表实现方法分析
2018/07/30 Python
利用Python如何实现一个小说网站雏形
2018/11/23 Python
在python中利用opencv简单做图片比对的方法
2019/01/24 Python
Python实现多进程的四种方式
2019/02/22 Python
对python3.4 字符串转16进制的实例详解
2019/06/12 Python
python3模拟实现xshell远程执行liunx命令的方法
2019/07/12 Python
python实现动态数组的示例代码
2019/07/15 Python
浅谈Django QuerySet对象(模型.objects)的常用方法
2020/03/28 Python
Pycharm 使用 Pipenv 新建的虚拟环境(图文详解)
2020/04/16 Python
静态变量和实例变量的区别
2015/07/07 面试题
大学生的网络创业计划书
2013/12/26 职场文书
乡镇食品安全责任书
2014/07/28 职场文书
淘宝客服专员岗位职责
2015/04/07 职场文书
2015财务年度工作总结范文
2015/05/04 职场文书
导游词之重庆渣滓洞
2020/01/08 职场文书
SQL注入的实现以及防范示例详解
2021/06/02 MySQL
CSS实现五种常用的2D转换
2021/12/06 HTML / CSS