Python中yield和yield from的用法
yield 后面接的是 future 对象
调用方 委托生成器
yield from 直接给出循环后的结果
yield from 委托者和子生成器直接通信
yield from 直接处理stopIteration错误 并把结果返回
jieshou=yield chuanchu
左边是接收值 右边是传入值 既是生产者也是消费者
调用方 main 委托方 子生成器(位于委托方内部)
yield 同时接受值传递给等号左边的变量,同时返回其后面的变量给外面的函数
yield from 总结
看完代码,我们总结一下关键点:
- 子生成器生产的值,都是直接传给调用方的;调用方通过.send()发送的值都是直接传递给子生成器的;如果发送的是 None,会调用子生成器的__next__()方法,如果不是 None,会调用子生成器的.send()方法;
- 子生成器退出的时候,最后的return EXPR,会触发一个StopIteration(EXPR)异常;
- yield from表达式的值,是子生成器终止时,传递给StopIteration异常的第一个参数;
- 如果调用的时候出现StopIteration异常,委托生成器会恢复运行,同时其他的异常会向上 “冒泡”;
- 传入委托生成器的异常里,除了GeneratorExit之外,其他的所有异常全部传递给子生成器的.throw()方法;如果调用.throw()的时候出现了StopIteration异常,那么就恢复委托生成器的运行,其他的异常全部向上 “冒泡”;
- 如果在委托生成器上调用.close()或传入GeneratorExit异常,会调用子生成器的.close()方法,没有的话就不调用。如果在调用.close()的时候抛出了异常,那么就向上 “冒泡”,否则的话委托生成器会抛出GeneratorExit异常。
协程:子生成器报错会直接把错误返回给调用方
和函数调用差不多 和同步编码方式一样
协程里面耗时的操作 比如 IO,time.sleep 等不能单独成行
卸载内部 只能放在yield 或者 yield from 后面
def fun_inner():
i = 0
while True:
i = yield i #传什么就返回什么
def fun_outer():
a = 0
b = 1
inner = fun_inner()
inner.send(None)
while True:
a = inner.send(b)
b = yield a #b原来不管是什么值 都会变成传入的值,传出的值为a
if name == ‘main’:
outer = fun_outer()
outer.send(None)
for i in range(5):
print(outer.send(i))
下面是yield from的实现方式:
def fun_inner():
i = 0
while True:
i = yield i
def fun_outer():
yield from fun_inner() #直接返回另一个生成器产生的值
直接调用另一个生成器
if name == ‘main’:
outer = fun_outer()
outer.send(None)
for i in range(5):
print(outer.send(i))
Python中yield和yield from的用法
</h1><div class="clear"></div><div class="postBody">
yield
python中yield的用法很像return,都是提供一个返回值,但是yield和return的最大区别在于,return一旦返回,则代码段执行结束,但是yield在返回值以后,会交出CUP的使用权,代码段并没有直接结束,而是在此处中断,当调用send()或者next()方法之后,yield可以从之前中断的地方继续执行。
在一个函数中,使用yield关键字,则当前的函数会变成生成器。
下面生成一个斐波那契数列。
def fib(n):index = 0a = 0b = 1
<span class="hljs-keyword">while</span> index < <span class="hljs-symbol">n:</span><span class="hljs-keyword">yield</span> ba,b = b, a+bindex += <span class="hljs-number">1</span></code></pre>
- 生成器对象
fib = fib(100)
print(fib)
打印出来的结果是一个生成器对象,并没有直接把我们想要的值打印出来。
- next()方法
fib = fib(100)
print(next(fib))
print(next(fib))
print(next(fib))
print(next(fib))
它的执行顺序是这样的,每次yield返回之后,程序将会中断,当出现next(fib)之后,程序将会从之前中断的地方继续执行。 python新版本中,不再提供fib.next()
方法。
- send()方法
使用send()方法允许我们向生成器中传值。
import time
def fib(n):
index = 0
a = 0
b = 1
<span class="hljs-keyword">while</span> <span class="hljs-keyword">index</span> < n:<span class="hljs-keyword">sleep</span> = yield b<span class="hljs-keyword">print</span>(<span class="hljs-string">'等待%s秒'</span> %sleep)time.sleep(<span class="hljs-keyword">sleep</span>)a,b = b, a+b<span class="hljs-keyword">index</span> += <span class="hljs-number">1</span>
fib = fib(20)
print(fib.send(None)) # 效果等同于print(next(fib))
print(fib.send(2))
print(fib.send(2))
print(fib.send(2))
print(fib.send(2))
执行顺序如下:
首先,创建生成器对象
调用fib.send(None)方法,此处作用与next(fib)相同,程序返回当前b的值1, 程序中断。
调用fib.send(2)方法,程序被唤醒,将2传递给yield之前的变量sleep,程序继续运行,直到遇到yield将新的b返回,程序再次中断。
如此继续下去,直到程序结束。
yield from
前面的都是单一层次的生成器,并没有嵌套,如果是多个生成器嵌套会怎么样呢,下面是一个例子。
def fun_inner():i = 0while True:i = yield i
def fun_outer():
a = 0
b = 1
inner = fun_inner()
inner.send(None)
while True:
a = inner.send(b)
b = yield a
if name == ‘main’:
outer = fun_outer()
outer.send(None)
for i in range(5):
print(outer.send(i))
在两层嵌套的情况下,值的传递方式是,先把值传递给外层生成器,外层生成器再将值传递给外层生成器,内层生成器在将值反向传递给外层生成器,最终yield出结果。如果嵌套的层次更多,传递将会越麻烦。
下面是yield from的实现方式:
def fun_inner():i = 0while True:i = yield i
def fun_outer():
yield from fun_inner()
if name == ‘main’:
outer = fun_outer()
outer.send(None)
for i in range(5):
print(outer.send(i))
效果是一样的,但是明显的代码量减少了,嵌套传值的时候,并不需要我们手动实现。
<div id="blog_post_info">
关注 - 0
粉丝 - 85
<div class="clear"></div>
<div id="post_next_prev"><a href="https://www.cnblogs.com/cnkai/p/7514815.html" class="p_n_p_prefix">« </a> 上一篇: <a href="https://www.cnblogs.com/cnkai/p/7514815.html" title="发布于 2017-09-13 14:35">Python多进程</a>
<br>
<a href="https://www.cnblogs.com/cnkai/p/7538260.html" class="p_n_p_prefix">» </a> 下一篇: <a href="https://www.cnblogs.com/cnkai/p/7538260.html" title="发布于 2017-09-17 22:28">Selenium快速入门(上)</a>
</div>
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191018154227110.jpg)
Python中yield和yield from的用法相关推荐
- python中list[1啥意思_详解Python中list[::-1]的几种用法
本文主要介绍了Python中list[::-1]的几种用法,分享给大家,具体如下: s = "abcde" list的[]中有三个参数,用冒号分割 list[param1:para ...
- python中os.path.join()的循环用法_Python中.join()和os.path.join()两个函数的用法详解
Python中有.join()和os.path.join()两个函数,具体作用如下: . join(): 连接字符串数组.将字符串.元组.列表中的元素以指定的字符(分隔符)连接生成一个新的字符串 ...
- python items函数用法,Python中dictionary items()系列函数的用法实例
本文实例讲述了Python中dictionary items()系列函数的用法,对Python程序设计有很好的参考借鉴价值.具体分析如下: 先来看一个示例: import html # availab ...
- python enumerate函数_关于python中enumerate和zip函数的用法及举例
关于python中enumerate和zip函数的用法及举例 关于enumerate函数: enumerate函数可以同时返回列表或元组等可迭代对象的下标和内容,但实际上,enumerate函数实际返 ...
- python中关于try,expect的用法
python中关于try,expect的用法 try: code except Error1 as e: #处理Error1异常 print(e) 上式说明,运行code,如果code恰巧出现了Err ...
- python中all()和any()函数的用法
python中all()和any()函数的用法 若判断两个数组相等,all()函数表示的是数组中所有数都要相等才输出TRUE,any()函数则是只要有一个数相等则就输出TRUE.如下代码所示: imp ...
- 一文搞定python中的multiply()和dot以及用法
python中的multiply()和dot以及*用法.md 首先创建如下的数组和矩阵,其中a,b为数组,A,B为矩阵 import numpy as npa = np.arange(1,5).res ...
- python中的or的两种用法
python中的or的两种用法 python中or除了常见的和and作为判断的条件外,还有一种不多见但很实用的用法,那就是: a = b or c 在这条赋值语句中的 or 的含义是判断 b 和 c ...
- python中的os abort_Python os.abort()用法及代码示例
Python中的OS模块提供了与操作系统进行交互的功能.操作系统属于Python的标准实用程序模块.该模块提供了使用依赖于操作系统的功能的便携式方法. os.abort()Python中的方法用于生成 ...
- python中的os abort_Python os.abort()用法及代碼示例
Python中的OS模塊提供了與操作係統進行交互的功能.操作係統屬於Python的標準實用程序模塊.該模塊提供了使用依賴於操作係統的功能的便攜式方法. os.abort()Python中的方法用於生成 ...
最新文章
- 基于redis的悲观锁实现
- MySQL数据库性能优化--SQL优化
- Python3编程语言之zip() 函数使用示例
- Linux基础篇之文本、数据流处理命令(sed uniq grep awk wc)
- coreldraw的线条怎么变成圆头_别再穿到处撞的小白鞋了,这五款春夏小皮鞋,不管怎么搭配都好看...
- MySQL使用详解--根据个人学习总结
- 历史重现,德国海关突袭IFA大展
- 73页PPT,教你从0到1构建用户画像系统(附下载)
- jsp table 中多出行数据_数据分析 | 如何基于高斯曲线拟合15分钟生活圈距离衰减规律...
- Eclipse Error:“ An API baseline has not been set ” 解决办法
- Symbian面试题
- 软件项目的规模、工作量和成本是如何进行估算或评估的?
- 计算机网络文化基础心得体会,提高计算机文化基础教学效果的几点心得
- Navicat无法导入excel文件的异常处理
- js怎么实现ftp上传文件到服务器,js ftp上传文件到服务器上
- [Vuforia]二.3D物体识别
- 支付宝APP支付 (JAVA生成支付信息,uniapp拉起支付宝支付)
- golang 如何快速测试代码
- ERROR:Xst:899--FPGA ERROR
- 【Python】天气预报及雨量预警到企业微信群的代码实现