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 并发是现实世界的本质特征,而聪明的计算机科学家用来模拟并发的技术手段便是多任务机制.大致上 ...
随机推荐
- Go 每日一库之 flag
缘起 我一直在想,有什么方式可以让人比较轻易地保持每日学习,持续输出的状态.写博客是一种方式,但不是每天都有想写的,值得写的东西. 有时候一个技术比较复杂,写博客的时候经常会写着写着发现自己的理解有偏 ...
- 机器学习新手必看:Jupyter Notebook入门指南
参考网址:https://blog.csdn.net/guleileo/article/details/80490921
- Proxmox VE:自建虚拟化方案
Proxmox VE 简介 Proxmox Virtual Environment,或 Proxmox VE,是来自德国的开源虚拟化方案.软件和社区支持都是免费的,企业用户则可以通过订阅制获得付费商业 ...
- @RequestParam,@PathVariable,@RequestBody
@RequestParam 和 @PathVariable 注解是用于从request中接收请求的,两个都可以接收参数,关键点不同的是@RequestParam 是从request里面拿取值,而 @P ...
- 为什么Mozilla Thunderbird无法登陆腾讯企业邮?
(一)问题描述 登陆腾讯企业邮提示"无法登录到服务器.可能是配置.用户名或者密码错误." (二)解决方案 手动配置 IMAP | imap.exmail.qq.com | 993 ...
- mysql中更改字符集为utf8&&mysql中文输入不了问题解决
写给TT:对不起啦!! 嗯,输入不了中文,大多数问题是mysql的字符集设置的问题,当然,别的问题也有可能, 这里我们用两种方法设置mysql的字符集,图形化工具和命令行的方式(一种操作完即可) 一, ...
- Linux系统终端session保持服务工具-Tmux
Tmux是非常流行的终端复用软件,通过一个终端登录远程主机并运行tmux后,在其中可以开启多个控制台而无需再“浪费”多余的终端来连接这台远程主机.相对于Screen,它更加先进:支持屏幕切分,而且具备 ...
- allegro使用经验总结(一)
在用allegro开发flappy bird.游戏虽然小,但是用到了allegro的方方面面,可以说是"麻雀虽小五脏俱全". 1.physfs 这是一个跨平台的读写文件的库,可以直 ...
- SpringBoot配置国际化
1).国际化 1).编写国际化配置文件: 2).使用ResourceBundleMessageSource管理国际化资源文件 3).在页面使用fmt:message取出国际化内容 步骤: 1).编写国 ...
- 机器学习笔记P1(李宏毅2019)
该博客将介绍机器学习课程by李宏毅的前两个章节:概述和回归. 视屏链接1-Introduction 视屏链接2-Regression 该课程将要介绍的内容如下所示: 从最左上角开始看: Regress ...