yield的英文单词意思是生产,刚接触Python的时候感到非常困惑,一直没弄明白yield的用法。一直到稀里糊涂的看完了廖雪峰的python博客也没彻底明白。
有一次不小心看到了这个文章,是转载的,原文出自哪里我也不知道,08年的文章,python2.5的,于是我按照3.6的标准重新定义一下,最后会附上源码

python2和python3是不兼容的,通篇环境都是python3.6

简单的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应用的一个例子,但是,看过很多东西,并自己反复体验后,对yield有了一个全新的理解,其中这篇算是精品了。

包含yield的函数

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

def h():print('study yield')yield 5print('go on!')h()

可以看到,调用h()之后,print 语句并没有执行!这就是yield。具体的内容后面会越来越清晰,包括yield的工作原理。

yield是一个表达式

python 2.5以前,yield是一个语句,我也没有考证,因为早都不用了,现在yield是一个表达式:

m = yield 5

表达式(yield 5)的返回值将赋值给m,所以,m = 5 肯定是错的。

那么如何获取(yield 5)的返回值呢?需要用到send(msg)

yield工作原理

揭晓yield的工作原理,需要配合next()函数。上面的h()被调用后并没有执行,因为它有yield表达式,通过next()可以恢复Generator执行,直到下一个yield

def h():print('study yield')yield 5print('go on!')c = h()
d1 = next(c)  # study yield
d2 = next(c)
"""
study yield
go on!
Traceback (most recent call last):File "D:/idea/workspace/pythonSpace/PythonDemo/static/yield_demo.py", line 35, in <module>d2 = next(c)
StopIteration
"""

next()被调用后,h()开始执行,直到遇到yield 5

因此输出结果是:study yield

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

study yield
go on!
Traceback (most recent call last):File "D:/idea/workspace/pythonSpace/PythonDemo/static/yield_demo.py", line 35, in <module>d2 = next(c)
StopIteration

send(msg) 与 next()

了解了next()如何让包含yield的函数执行后,我们再来看另外一个非常重要的函数send(msg)

其实next()send()在一定意义上作用是相似的

区别

send()可以传递yield的值

next()只能传递None

所以next()send(None)作用是一样的。

def s():print('study yield')m = yield 5print(m)d = yield 16print('go on!')c = s()
s_d = next(c)  # 相当于send(None)
c.send('Fighting!')  # (yield 5)表达式被赋予了'Fighting!'

输出的结果为:

study yield
Fighting!

注意 生成器刚启动时(第一次调用),请使用next()语句或是send(None),不能直接发送一个非None的值,否则会报TypeError因为没有yield语句来接收这个值

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

send(msg)next() 的返回值比较特殊,是下一个yield表达式的参数(yield 5,则返回 5)。

到这里,第一个例子中,通过for i in alist 遍历 Generator,其实是每次都调用了next(),而每次next()的返回值正是yield的参数:

def s():print('study yield')m = yield 5print(m)d = yield 16print('go on!')c = s()
s_d1 = next(c)  # 相当于send(None)
s_d2 = c.send('Fighting!')  # (yield 5)表达式被赋予了'Fighting!'
print('My Birth Day:', s_d1, '.', s_d2)

输出结果:

study yield
Fighting!
My Birth Day: 5 . 16

中断Generator

上面的例子中,当没有可执行程序的时候,会抛出一个StopIteration, 开发过程中,中断Generator是一个非常灵活的技巧

throw

通过抛出一个GeneratorExit异常来终止Generator。

close

close的作用和throw是一样的,看它的源码,可以发现,它和raise一球样

def throw(self, type, value=None, traceback=None):'''Used to raise an exception inside the generator.'''# 用于在生成器中抛出一个异常。passdef close(self):'''Raises new GeneratorExit exception inside the generator to terminate the iteration.'''# 在生成器中生成新的GeneratorExit异常来终止迭代。pass

其实最后一个中断生成器可以忽略的,在开发过程中,不可避免的要用到这些,但是Python3内部已经做得很好了,一般不太需要手动去做这件事情。

demo地址

https://github.com/seeways/PythonDemo/blob/master/static/yield_demo.py

深入理解 Python yield相关推荐

  1. python yield理解_对Python中Yield的理解

    看到下面这段程序的时候,有点不明白这个yield到底是个啥东西,看了网上很多的博客,大致理解了yield的含义,所以记录下来. 要说yield首先要说python中的生成器,那么什么是生成器? 假设有 ...

  2. 彻底理解Python中的yield

    阅读别人的python源码时碰到了这个yield这个关键字,各种搜索终于搞懂了,在此做一下总结: 通常的for...in...循环中,in后面是一个数组,这个数组就是一个可迭代对象,类似的还有链表,字 ...

  3. 深入理解Python中的yield和send

    send方法和next方法唯一的区别是在执行send方法会首先把上一次挂起的yield语句的返回值通过参数设定,从而实现与生成器方法的交互. 但是需要注意,在一个生成器对象没有执行next方法之前,由 ...

  4. 理解Python中的yield

    理解Python中的yield 参考文献 本文浅谈自己对Python中yield关键字的理解. yield可以理解成return,但是它与return又不完全相同.在Python中,yield关键字是 ...

  5. 深入理解Python的With-as语句

    学习Python有一段时间了,最近做一个项目会涉及到文件的读取和关闭.比如:我想把一些对象序列化到文件里面,然后当我再次使用的时候,在从文件里面读取反序列化成对象.像这种操作一般都是用try-exce ...

  6. c++ 协程_理解Python协程(Coroutine)

    由于GIL的存在,导致Python多线程性能甚至比单线程更糟. GIL: 全局解释器锁(英语:Global Interpreter Lock,缩写GIL),是计算机程序设计语言解释器用于同步线程的一种 ...

  7. python3 协程 写法_理解Python的协程(Coroutine)

    由于GIL的存在,导致Python多线程性能甚至比单线程更糟. GIL: 全局解释器锁(英语:Global Interpreter Lock,缩写GIL),是计算机程序设计语言解释器用于同步线程的一种 ...

  8. python在线搭建教程_理解python web开发,轻松搭建web app!

    大家好,今天分享给大家的是理解python web开发,轻松搭建web app,希望大家学有所获! 因为 python代码的优雅美观且易于维护这一特点,越来越多的人选择使用 Python做web开发. ...

  9. python iterable对象_如何理解Python中的iterable对象

    转载请注明出处:https://www.jianshu.com/u/5e6f798c903a [^*] 表示注脚,在文末可以查看对应连接,但简书不支持该语法. 首先,容器和 iterable 间没有必 ...

最新文章

  1. 206. Reverse Linked List
  2. springboot 集成mybatis时日志输出
  3. AOP 中必须明白的概念-目标对象(Target Object)
  4. 如何将bing搜索页面以HTML Mashup的方式嵌入到SAP C4C页面
  5. Android之mediarecorder中的方法以及工作流程的过程
  6. Python学习1——Python中的 split() 函数
  7. 被指涉嫌“二选一” 山姆回应:欢迎良性竞争
  8. python爬虫爬取豆瓣电影
  9. Es6 filter()、map()、find()方法详解
  10. Android Studio中竟然还能加入一个程序员鼓励师
  11. php爬虫入门之phpspider框架
  12. 逻辑回归实现文本分类
  13. 随心所遇,随遇而安。
  14. java-php-python-ssm网上游戏商店设计计算机毕业设计
  15. 计算机科学家手抄报图片,关于简洁又漂亮的科学手抄报图片
  16. python3删除重复文件,可用命令行
  17. ride.py在运行python3.×版本后导致无法运行及解决办法
  18. 【数学】三角函数小题
  19. APS54083 DC/DC升降压恒流驱动芯片 2.4G调光 —提供DEMO板
  20. Neural Voice Puppetry阅读笔记

热门文章

  1. qq公众平台出错了609_微信附近人功能无法使用,到底是平台出了差错还是由于自我原因。...
  2. 11GR2 中的常见 RMAN 问题
  3. 电脑为什么会蓝屏的原因
  4. 这个城市最安静的声音 - Suzy
  5. Berzerk CodeForces - 787C (BFS)题解
  6. Kitty: 又一款基于 GPU 加速的终端工具
  7. Windows:MULTIPROCESSOR CONFIGURATION NOT SUPPORTED蓝屏(32位(win10/LTSC 2019/LTSC 2021))
  8. 论文总结 -论文写作注意事项(持续更)
  9. 如果不做测试了,自己还能干点啥?
  10. 会动的小狗纯HTML代码