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的更多相关文章

  1. ngx_lua_API 指令详解(五)coroutine.create,coroutine.resume,coroutine.yield 等集合指令介绍

    ngx_lua 模块(原理实现) 1.每个worker(工作进程)创建一个Lua VM,worker内所有协程共享VM: 2.将Nginx I/O原语封装后注入 Lua VM,允许Lua代码直接访问: ...

  2. Python协程:从yield/send到async/await

    这个文章理好了脉落. http://python.jobbole.com/86069/ 我练 习了一番,感受好了很多... Python由于众所周知的GIL的原因,导致其线程无法发挥多核的并行计算能力 ...

  3. lua coroutine for iterator

    背景 前面的文章演示了使用闭包函数实现 状态的迭代器. 本文演示使用 coroutine来产生迭代器的例子. coroutine迭代器例子 -- 遍历二叉树 local binary_tree = { ...

  4. Lua Coroutine详解

    协同程序与线程差不多,也就是一条执行序列,拥有自己独立的栈,局部变量和指令指针,同时又与其它协同程序共享全局变量和其它大部分东西.线程与协同程序的主要区别在于,一个具有多线程的程序可以同时运行几个线程 ...

  5. Lua 协程coroutine

    协程和一般多线程的区别是,一般多线程由系统决定该哪个线程执行,是抢占式的,而协程是由每个线程自己决定自己什么时候不执行,并把执行权主动交给下一个线程. 协程是用户空间线程,操作系统其存在一无所知,所以 ...

  6. 【转】Lua coroutine 不一样的多线程编程思路

    Lua coroutine 不一样的多线程编程思路 Sunday, Apr 26th, 2009 by Tim | Tags: coroutine, Lua 上周末开始看<Lua程序设计> ...

  7. Lua中的协同程序 coroutine

    Lua中的协程和多线程很相似,每一个协程有自己的堆栈,自己的局部变量,可以通过yield-resume实现在协程间的切换.不同之处是:Lua协程是非抢占式的多线程,必须手动在不同的协程间切换,且同一时 ...

  8. JSBinding + SharpKit / Coroutine支持

    首先得深入了解协程的原理.如果还没有完全理解,建议看这篇: http://wiki.unity3d.com/index.php/CoroutineScheduler 另外还要对 JavaScript ...

  9. (zt)Lua的多任务机制——协程(coroutine)

    原帖:http://blog.csdn.net/soloist/article/details/329381 并发是现实世界的本质特征,而聪明的计算机科学家用来模拟并发的技术手段便是多任务机制.大致上 ...

随机推荐

  1. 【GeneXus】开发移动APP时,如何使用Canvas进行布局?

    当我们开发移动端APP的时候,经常遇到一种布局方式,那就是层级的布局,比如:一张照片我想在照片的上面显示它的名称,但不影响我照片展示的布局大小,也就是这个名称是浮在照片上的,如图: 如果要实现这样的布 ...

  2. js的alert()

    效果图: 图一: 图二: 图三: 代码: <script type="text/javascript"> // alert() ; 只允许一个参数,如果有多个参数只显示 ...

  3. Spring Boot2 系列教程 (十七) | 整合 WebSocket 实现聊天室

    微信公众号:一个优秀的废人.如有问题,请后台留言,反正我也不会听. 前言 昨天那篇介绍了 WebSocket 实现广播,也即服务器端有消息时,将消息发送给所有连接了当前 endpoint 的浏览器.但 ...

  4. 小程序中的pick

    picker:从底部弹起的滚动选择器. 属性:model  string类型  说明:选择器类型 : selector  普通选择器 multiSelector   多列选择器 time   时间选择 ...

  5. SpringMVC启动流程源码解密

    我们知道,SpringMVC最后是通过Tomcat来进行部署的.当在Servlet中进行进行应用部署时,主要步骤为(引用来自http://download.oracle.com/otn-pub/jcp ...

  6. LeetCode 第27题--移除元素

    1. 题目 2.题目分析与思路 3.代码 1. 题目 给定 nums = [3,2,2,3], val = 3, 函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2. 你不需要考虑数组 ...

  7. javaweb-codereview 学习记录-2

    1.Java 文件名空字节截断漏洞(%00 Null Bytes) 受空字节截断影响的JDK版本范围:JDK<1.7.40 实际上修复就是检查文件名中是否包含\u0000,包含则为非法路径 fi ...

  8. [bzoj1041] [洛谷P2508] [HAOI2008] 圆上的整点

    Description 求一个给定的圆(x^2+y^2=r^2),在圆周上有多少个点的坐标是整数. Input 只有一个正整数n,n<=2000 000 000 Output 整点个数 Samp ...

  9. IO系统-标准C的I/O和文件I/O

    1.标准C的I/O 1.1常用函数和结构体 char *fgets(char *s, int size, FILE *stream); //整行输入 int printf(const char *fo ...

  10. 20191212模拟赛 问题B

    题目: 分析: 上来看到k=2,... SB杜教筛phi 有点感冒,这把养生一点... 于是写了55分走人了.. 下来一看挺简单的啊2333 不考虑gcd时,构造数列的方案为C(N+K-1,K) 考虑 ...