yield的英文单词意思是生产,刚接触Python的时候感到非常困惑,一直没弄明白yield的用法。 只是粗略的知道yield可以用来为一个函数返回值塞数据,比如下面的例子:

 1 def addlist(alist):
 2     for i in alist:
 3         yield i+1
 4
 5 alist=[1,2,3,4]
 6 for x in addlist(alist):
 7     print(x)
 8 #输出是:
 9 2
10 3
11 4
12 5
13 [Finished in 0.2s]

  取出alist的每一项,然后把i + 1塞进去。然后通过调用取出每一项; 这的确是yield应用的一个例子

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

1 def h():
2     print('To be brave')
3     yield 5
4 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表达式处。比如:

 1 def h():
 2     print ('Wen Chuan')
 3     yield 5
 4     print ('Fighting!')
 5 c = h()
 6 c.__next__()
 7 next(c)
 8
 9 #输出为:
10 Traceback (most recent call last):
11   File "C:\Users\zhangp\Desktop\md5.py", line 69, in <module>
12 Wen Chuan
13 Fighting!
14     next(c)
15 StopIteration
16 [Finished in 0.1s with exit code 1]

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

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

   4. send(msg) 与 next()

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

1 2 3 4 5 6 7 8 9 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的参数,即我们开始认为被压进去的东东。我们再延续上面的例子: 1 2 3 4 5 6 7 8 9 10 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 输出结果: 1 2 Wen Chuan Fighting! We will never forget the date 5 . 12 6. throw() 与 close()中断 Generator 中断Generator是一个非常灵活的技巧,可以通过throw抛出一个GeneratorExit异常来终止Generator。Close()方法作用是一样的,其实内部它是调用了throw(GeneratorExit)的。我们看: 1 2 3 4 5 6 7 8 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)的话会抛出一个异常: 1 2 3 4 Traceback (most recent call last): File "/home/evergreen/Codes/yidld.py", line 14, in d = c.send('Fighting!') #d 获取了yield 12 的参数值12 StopIteration 调用next()函数返回的是yield后面的值,yield表达式的值不是yield后面跟着的东西,而是通过send()函数传入进去的值,传入的值赋值给当前yield表达式的值,详细见下面代码 [python] view plain copy def f(): print('start') a = yield 1 print(a) print('middle....') b = yield 2 #2这个值只是迭代值,调用next时候返回的值 print(b) #传入的参数是给当前yield的,也就是yield 2,因为当前函数走到了yield 2,所以传入的参数没有给yield 1 print('next') c = yield 3 print(c) a = f() next(a) next(a) a.send('msg') 结果是: [python] view plain copy start None middle.... msg next [Finished in 0.2s]

转载于:https://www.cnblogs.com/AlwaysWIN/p/6591710.html

Python深入理解yield相关推荐

  1. 五分钟理解yield在python中的简单用法,让你不再迷惑

    很多同学无论是在学习python还是使用python的过程中,都会遇到yield关键字,这个让人头大的问题,今天,就给大家分享一下我自学yield的心路历程 基本概念: (1)在 Python 中,使 ...

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

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

  3. Python天天美味(25) - 深入理解yield

    yield的英文单词意思是生产,刚接触Python的时候感到非常困惑,一直没弄明白yield的用法.只是粗略的知道yield可以用来为一个函数返回值塞数据,比如下面的例子: def  addlist( ...

  4. 理解Python中的yield

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

  5. python中yield讲解_「技术」如何深入理解Python中的 yield?

    深入理解 yield 为了理解什么是 yield,你必须理解什么是生成器.在理解生成器之前,让我们先走近迭代. Iterables 当你建立了一个列表,你可以逐项地读取这个列表,这叫做一个可迭代对象: ...

  6. python协程--yield和yield from

    字典为动词"to yield"给出了两个释义:产出和让步.对于 Python 生成器中的 yield 来说,这两个含义都成立.yield item 这行代码会产出一个值,提供给 n ...

  7. 转载:Python 的关键字 yield 有哪些用法和用途?

    原始链接:https://www.zhihu.com/question/345210030/answer/841903171 Python 的关键字 yield 有哪些用法和用途? 飞鸿 人生到处知何 ...

  8. 如何理解yield的用法

    原创不易,转载前请注明博主的链接地址:Blessy_Zhu https://blog.csdn.net/weixin_42555080 本次代码的环境: 运行平台: Windows Python版本: ...

  9. python中row是什么意思_一文搞懂Python中的yield

    关注公众号「Python七号」,及时 get Python 技能. yield 可以实现生成器,可以实现协程. 什么是生成器,什么是协程,如果还不了解,可以继续往下看,概念可以不懂,只要理解它的作用和 ...

  10. Python字典理解

    本文翻译自:Python Dictionary Comprehension Is it possible to create a dictionary comprehension in Python ...

最新文章

  1. git error(win下)
  2. 使用PHP读取和创建txt,doc,xls,pdf类型文件
  3. 数据中台建设是噱头还是黑科技?
  4. php中删除评论怎么做的,php实现评论回复删除功能
  5. mysql 高效分页查询_PostgreSQL、MySQL高效分页方法探讨
  6. Android 起调第三方导航,百度地图,高德地图,腾讯地图。起调高德地图导航
  7. 编译安装php7.3
  8. 一个ubuntu phper的自我修养(lamp)
  9. Scala 基础(7)—— 函数字面量和一等函数
  10. CSS 居中 可随着浏览器变大变小而居中
  11. c++ opencv [ INFO:0] global c:\build\master_winpack-build-win64-vc15\***
  12. JS打开新窗口(window.open() 、href)
  13. git Untracked Files Prevent Rebase
  14. opencv中calcOpticalFlowPyrLK实现的光流法(Lucas-Kanade Method for Sparse Optical Flow)原理解析 (摘要翻译)
  15. 如何用burpsuite和手机模拟器给apk抓包
  16. elasticsearch报错:bootstrap checks failed. You must address the points described in the following [1]
  17. 明日之后最新服务器开服时间,明日之后什么时候开服 新服开区详解
  18. java里人带狗散步,不想带狗狗出门散步,告诉你5个遛狗的好处,不仅仅只有狗狗受益...
  19. 浙江工商大学计算机考试科目,浙江工商大学(专业学位)计算机技术研究生考试科目和考研参考书目...
  20. android 为什么不调用onDestroy方法关闭activity

热门文章

  1. LAMP架构调优(三)——模块的安装与调用
  2. 防火墙虚拟系统互访配置实例
  3. Node.js连接mysql报加密方式错误解决方案
  4. 大数据奏鸣曲,听出了什么?
  5. 【网络原理】期末复习笔记 第一章 概述
  6. .NET Core 中 IOptions 有什么用
  7. NO.170 六问禅道1:为什么任务的剩余工时不自动更新?
  8. [Bootstrap]组件(二)
  9. Python os 标准库使用
  10. Direct X 修复