Python yield的用法实例分析


Posted in Python onMarch 06, 2020

本文实例讲述了Python yield的用法。分享给大家供大家参考,具体如下:

yield的英文单词意思是生产,刚接触Python的时候感到非常困惑,一直没弄明白yield的用法。

只是粗略的知道yield可以用来为一个函数返回值塞数据,比如下面的例子:

def addlist(alist):
  for i in alist:
    yield i + 1

取出alist的每一项,然后把i + 1塞进去。然后通过调用取出每一项:

alist = [1, 2, 3, 4]
for x in addlist(alist):
  print x,

这的确是yield应用的一个例子

1.包含yield的函数

假如你看到某个函数包含了yield,这意味着这个函数已经是一个Generator,它的执行会和其他普通的函数有很多不同。比如下面的简单的函数:

def h():
  print 'To be brave'
  yield 5
h()

可以看到,调用h()之后,print 语句并没有执行!这就是yield,那么,如何让print 语句执行呢?这就是后面要讨论的问题,通过后面的讨论和学习,就会明白yield的工作原理了。

2.yield是一个表达式

Python2.5以前,yield是一个语句,但现在2.5中,yield是一个表达式(Expression),比如:

m = yield 5

表达式(yield 5)的返回值将赋值给m,所以,认为 m = 5 是错误的。那么如何获取(yield 5)的返回值呢?需要用到后面要介绍的send(msg)方法。

3.透过next()语句看原理

现在,我们来揭晓yield的工作原理。我们知道,我们上面的h()被调用后并没有执行,因为它有yield表达式,因此,我们通过next()语句让它执行。next()语句将恢复Generator执行,并直到下一个yield表达式处。比如:

def h():
  print 'Wen Chuan'
  yield 5
  print 'Fighting!'
c = h()
c.next()

c.next()调用后,h()开始执行,直到遇到yield 5,因此输出结果:

Wen Chuan

当我们再次调用c.next()时,会继续执行,直到找到下一个yield表达式。由于后面没有yield了,因此会??出异常:

Wen Chuan
Fighting!
Traceback (most recent call last):
  File "/home/evergreen/Codes/yidld.py", line 11, in <module>
    c.next()
StopIteration

4.send(msg) 与 next()

了解了next()如何让包含yield的函数执行后,我们再来看另外一个非常重要的函数send(msg)。其实next()和send()在一定意义上作用是相似的,区别是send()可以传递yield表达式的值进去,而next()不能传递特定的值,只能传递None进去。因此,我们可以看做

c.next() 和 c.send(None) 作用是一样的。

来看这个例子:

def h():
  print 'Wen Chuan',
  m = yield 5 # Fighting!
  print m
  d = yield 12
  print 'We are together!'
c = h()
c.next() #相当于c.send(None)
c.send('Fighting!') #(yield 5)表达式被赋予了'Fighting!'

输出的结果为:

Wen Chuan Fighting!

需要提醒的是,第一次调用时,请使用next()语句或是send(None),不能使用send发送一个非None的值,否则会出错的,因为没有yield语句来接收这个值。

5.send(msg) 与 next()的返回值

send(msg) 和 next()是有返回值的,它们的返回值很特殊,返回的是下一个yield表达式的参数。比如yield 5,则返回 5 。到这里,是不是明白了一些什么东西?本文第一个例子中,通过for i in alist 遍历 Generator,其实是每次都调用了alist.Next(),而每次alist.Next()的返回值正是yield的参数,即我们开始认为被压进去的东东。我们再延续上面的例子:

def h():
  print 'Wen Chuan',
  m = yield 5 # Fighting!
  print m
  d = yield 12
  print 'We are together!'
c = h()
m = c.next() #m 获取了yield 5 的参数值 5
d = c.send('Fighting!') #d 获取了yield 12 的参数值12
print 'We will never forget the date', m, '.', d

输出结果:

Wen Chuan Fighting!
We will never forget the date 5 . 12

6.throw() 与 close()中断 Generator

中断Generator是一个非常灵活的技巧,可以通过throw抛出一个GeneratorExit异常来终止Generator。Close()方法作用是一样的,其实内部它是调用了throw(GeneratorExit)的。我们看:

def close(self):
  try:
    self.throw(GeneratorExit)
  except (GeneratorExit, StopIteration):
    pass
  else:
    raise RuntimeError("generator ignored GeneratorExit")
# Other exceptions are not caught

因此,当我们调用了close()方法后,再调用next()或是send(msg)的话会抛出一个异常:

Traceback (most recent call last):
  File "/home/evergreen/Codes/yidld.py", line 14, in <module>
    d = c.send('Fighting!')  #d 获取了yield 12 的参数值12
StopIteration

更多关于Python相关内容可查看本站专题:《Python数据结构与算法教程》、《Python Socket编程技巧总结》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》及《Python入门与进阶经典教程》

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
python算法学习之桶排序算法实例(分块排序)
Dec 18 Python
python使用nntp读取新闻组内容的方法
May 08 Python
pygame加载中文名mp3文件出现error
Mar 31 Python
python中的字典操作及字典函数
Jan 03 Python
python3+PyQt5重新实现QT事件处理程序
Apr 19 Python
一篇文章了解Python中常见的序列化操作
Jun 20 Python
OpenCV里的imshow()和Matplotlib.pyplot的imshow()的实现
Nov 25 Python
Python3和pyqt5实现控件数据动态显示方式
Dec 13 Python
如何使用Python破解ZIP或RAR压缩文件密码
Jan 09 Python
利用Tensorflow构建和训练自己的CNN来做简单的验证码识别方式
Jan 20 Python
Python爬虫爬取糗事百科段子实例分享
Jul 31 Python
Python打包exe时各种异常处理方案总结
May 18 Python
用Python生成HTML表格的方法示例
Mar 06 #Python
使用Python第三方库pygame写个贪吃蛇小游戏
Mar 06 #Python
Python修改列表值问题解决方案
Mar 06 #Python
浅谈matplotlib.pyplot与axes的关系
Mar 06 #Python
python-xpath获取html文档的部分内容
Mar 06 #Python
关于python中的xpath解析定位
Mar 06 #Python
Python网络爬虫信息提取mooc代码实例
Mar 06 #Python
You might like
php preg_filter执行一个正则表达式搜索和替换
2012/02/27 PHP
php 模拟get_headers函数的代码示例
2013/04/27 PHP
PHP Callable强制指定回调类型的方法
2016/08/30 PHP
PHP中类与对象功能、用法实例解读
2020/03/27 PHP
一些有关检查数据的JS代码
2006/09/07 Javascript
使javascript也能包含文件
2006/10/26 Javascript
JS getStyle获取最终样式函数代码
2010/04/01 Javascript
JS date对象的减法处理实现代码
2010/12/28 Javascript
html的DOM中document对象forms集合用法实例
2015/01/21 Javascript
JavaScript编写检测用户所使用的浏览器的代码示例
2016/05/05 Javascript
AngularJS 过滤器的简单实例
2016/07/27 Javascript
JavaScript中双符号的运算详解
2017/03/12 Javascript
JS中showModalDialog关闭子窗口刷新主窗口用法详解
2017/03/25 Javascript
JS中类的静态方法,静态变量,实例方法,实例变量区别与用法实例分析
2020/03/14 Javascript
[01:03:13]VG vs Pain 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
Python multiprocessing模块中的Pipe管道使用实例
2015/04/11 Python
python DataFrame获取行数、列数、索引及第几行第几列的值方法
2018/04/08 Python
python 日志增量抓取实现方法
2018/04/28 Python
Python并发:多线程与多进程的详解
2019/01/24 Python
Python使用pandas和xlsxwriter读写xlsx文件的方法示例
2019/04/09 Python
Python3 itchat实现微信定时发送群消息的实例代码
2019/07/12 Python
通过python调用adb命令对App进行性能测试方式
2020/04/23 Python
pycharm远程连接vagrant虚拟机中mariadb数据库
2020/06/05 Python
Python实现列表索引批量删除的5种方法
2020/11/16 Python
意大利在线药房:shop-farmacia.it
2019/03/12 全球购物
DOUGLAS荷兰:购买香水和化妆品
2020/10/24 全球购物
SQL Server数据库笔试题和答案
2016/02/04 面试题
亿阳信通股份有限公司C#笔试题
2016/12/06 面试题
技校学生个人职业生涯规划范文
2014/03/03 职场文书
cf收人广告词
2014/03/14 职场文书
《鲁班和橹板》教学反思
2014/04/27 职场文书
撤诉状格式范本
2015/05/19 职场文书
党支部半年考察意见
2015/06/01 职场文书
《坐井观天》教学反思
2016/02/18 职场文书
导游词之安徽九华山
2019/09/18 职场文书
教你漂亮打印Pandas DataFrames和Series
2021/05/29 Python