coroutine - yield from
yield from
yield from x 表达式对 x 对象所做的第一件事是,调用 iter(x),从中获取迭代器。因
此, x 可以是任何可迭代的对象。
可是,如果 yield from 结构唯一的作用是替代产出值的嵌套 for 循环,这个结构很有
可能不会添加到 Python 语言中。 yield from 结构的本质作用无法通过简单的可迭代对象
说明,而要发散思维,使用嵌套的生成器。因此,引入 yield from 结构的 PEP 380 才起
了“Syntax for Delegating to a Subgenerator”(“把职责委托给子生成器的句法”)这个标题。
yield from 的主要功能是打开双向通道,把最外层的调用方与最内层的子生成器连接起
来,这样二者可以直接发送和产出值,还可以直接传入异常,而不用在位于中间的协程中
添加大量处理异常的样板代码。有了这个结构,协程可以通过以前不可能的方式委托职责。
若想使用 yield from 结构,就要大幅改动代码。为了说明需要改动的部分, PEP 380 使
用了一些专门的术语。 委派生成器
包含 yield from <iterable> 表达式的生成器函数。 子生成器
从 yield from 表达式中 <iterable> 部分获取的生成器。这就是 PEP 380 的标题
(“Syntax for Delegating to a Subgenerator”)中所说的“子生成器”(subgenerator)。 调用方
PEP 380 使用“调用方”这个术语指代调用委派生成器的客户端代码。 子生成器可能是简单的迭代器,只实现了 __next__ 方法;但是, yield from 也能处理这种子生成器。
不过,引入 yield from 结构的目的是为了支持实现了 __next__、 send、 close 和throw 方法的生成器。 如果子生成器不终止,委派生成器会在 yield from 表达式处永远暂停。如果是这样,程序不会向前执行,
因为 yield from(与 yield 一样)把控制权转交给客户代码(即,委派生成器的调用方)了。显然,
肯定有任务无法完成. 因为委派生成器相当于管道,所以可以把任意数量个委派生成器连接在一起:一个委派生成器使用
yield from 调用一个子生成器,而那个子生成器本身也是委派生成器,使用 yield from
调用另一个子生成器,以此类推。最终,这个链条要以一个只使用 yield 表达式的简单生成器结束;
不过,也能以任何可迭代的对象结束. 任何 yield from 链条都必须由客户驱动,在最外层委派生成器上调用 next(...) 函数
或 .send(...) 方法。可以隐式调用,例如使用 for 循环。 批准后的 PEP 380 在“Proposal”一节(https://www.python.org/dev/peps/pep-0380/#proposal)
分六点说明了 yield from 的行为。
a, 子生成器产出的值都直接传给委派生成器的调用方(即客户端代码)。
b, 使用 send() 方法发给委派生成器的值都直接传给子生成器。如果发送的值是
None,那么会调用子生成器的 __next__() 方法。如果发送的值不是 None,那么会
调用子生成器的 send() 方法。如果调用的方法抛出 StopIteration 异常,那么委
派生成器恢复运行。任何其他异常都会向上冒泡,传给委派生成器。
c, 生成器退出时,生成器(或子生成器)中的 return expr 表达式会触发
StopIteration(expr) 异常抛出。
d, yield from 表达式的值是子生成器终止时传给 StopIteration 异常的第一个参数。
e, yield from 结构的另外两个特性与异常和终止有关。传入委派生成器的异常,
除了 GeneratorExit 之外都传给子生成器的 throw() 方法。如果调用 throw()
方法时抛出 StopIteration 异常,委派生成器恢复运行。 StopIteration 之外的
异常会向上冒泡,传给委派生成器。
f, 如果把 GeneratorExit 异常传入委派生成器,或者在委派生成器上调用 close() 方
法,那么在子生成器上调用 close() 方法,如果它有的话。如果调用 close() 方法
导致异常抛出,那么异常会向上冒泡,传给委派生成器;否则,委派生成器抛出 GeneratorExit 异常。
coroutine - yield from的更多相关文章
- ngx_lua_API 指令详解(五)coroutine.create,coroutine.resume,coroutine.yield 等集合指令介绍
ngx_lua 模块(原理实现) 1.每个worker(工作进程)创建一个Lua VM,worker内所有协程共享VM: 2.将Nginx I/O原语封装后注入 Lua VM,允许Lua代码直接访问: ...
- Python协程:从yield/send到async/await
这个文章理好了脉落. http://python.jobbole.com/86069/ 我练 习了一番,感受好了很多... Python由于众所周知的GIL的原因,导致其线程无法发挥多核的并行计算能力 ...
- lua coroutine for iterator
背景 前面的文章演示了使用闭包函数实现 状态的迭代器. 本文演示使用 coroutine来产生迭代器的例子. coroutine迭代器例子 -- 遍历二叉树 local binary_tree = { ...
- Lua Coroutine详解
协同程序与线程差不多,也就是一条执行序列,拥有自己独立的栈,局部变量和指令指针,同时又与其它协同程序共享全局变量和其它大部分东西.线程与协同程序的主要区别在于,一个具有多线程的程序可以同时运行几个线程 ...
- Lua 协程coroutine
协程和一般多线程的区别是,一般多线程由系统决定该哪个线程执行,是抢占式的,而协程是由每个线程自己决定自己什么时候不执行,并把执行权主动交给下一个线程. 协程是用户空间线程,操作系统其存在一无所知,所以 ...
- 【转】Lua coroutine 不一样的多线程编程思路
Lua coroutine 不一样的多线程编程思路 Sunday, Apr 26th, 2009 by Tim | Tags: coroutine, Lua 上周末开始看<Lua程序设计> ...
- Lua中的协同程序 coroutine
Lua中的协程和多线程很相似,每一个协程有自己的堆栈,自己的局部变量,可以通过yield-resume实现在协程间的切换.不同之处是:Lua协程是非抢占式的多线程,必须手动在不同的协程间切换,且同一时 ...
- JSBinding + SharpKit / Coroutine支持
首先得深入了解协程的原理.如果还没有完全理解,建议看这篇: http://wiki.unity3d.com/index.php/CoroutineScheduler 另外还要对 JavaScript ...
- (zt)Lua的多任务机制——协程(coroutine)
原帖:http://blog.csdn.net/soloist/article/details/329381 并发是现实世界的本质特征,而聪明的计算机科学家用来模拟并发的技术手段便是多任务机制.大致上 ...
随机推荐
- Scala实践10
1.模式匹配 模式匹配是一种根据模式检查值的机制.它是switch(Java中语句)的更强大版本,它同样可以用来代替一系列if / else语句. 句法 匹配表达式具有值,match关键字和至少一个c ...
- Redis-缓存穿透、缓存雪崩、缓存击穿、缓存一致性、并发竞争
缓存流程 在讲这五个问题之前,首先我们回顾下正常的缓存的使用流程 程序在处理请求时,会先从缓存中进行查询,如果缓存中没有对应的key,则会从数据库中查询,如果查询到结果,并将查询结果添加到缓存中去,反 ...
- P2365 任务安排 batch 动态规划
batch ★☆ 输入文件:batch.in 输出文件:batch.out 简单对比时间限制:1 s 内存限制:128 MB 题目描述 N个任务排成一个序列在一台机器上等待完成(顺序不 ...
- P3369 【模板】普通平衡树 01Trie树
P3369 [模板]普通平衡树 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入xx数 删除xx数(若有多个相同的数,因只删除一个) 查询xx数的排名(排名 ...
- cogs 619. [金陵中学2007] 传话 Tarjan强连通分量
619. [金陵中学2007] 传话 ★★ 输入文件:messagez.in 输出文件:messagez.out 简单对比时间限制:1 s 内存限制:128 MB [问题描述] 兴趣小 ...
- 秦皇岛 I 题
有 n 个数字,你可以挑选其中任意个数字代表一个背包的体积,其余的数字表示的物品的体积,所挑选的背包必选完全装满,询问最终的方案数 思路分析 : 定义dp[i] 表示挑选 i 状态下的物品的方案数,f ...
- cf - 920 c 求能否实现交换
C. Swap Adjacent Elements time limit per test 1 second memory limit per test 256 megabytes input sta ...
- DirectX11 Windows Windows SDK--28 计算着色器:波浪(水波)
前言 有关计算着色器的基础其实并不是很多.接下来继续讲解如何使用计算着色器实现水波效果,即龙书中所实现的水波.但是光看代码可是完全看不出来是在做什么的.个人根据书中所给的参考书籍找到了对应的实现原理, ...
- http请求头中的content-type属性
在HTTP请求中,我们每天都在使用Content-Type来指定不同格式的请求信息,但是却很少有人去全面了解Content-Type中允许的值有多少,因此这里来了解一下Content-Type的可用值 ...
- spring-cloud-gateway报错
2019-08-13 09:41:19.216 WARN [-,,,] 10084 --- [ main] ConfigServletWebServerApplicationContext : Exc ...