5)协程二(yeild from)
一:yield from说明
python从3.3版本开始使用yield from 替代yield
yield from 结构会在内部自动捕获 StopIteration 异常。
这种处理方式与 for 循环处理 StopIteration 异常的方式一样:循环机制使用用户易于理解的方式处理异常。
对 yield from 结构来说,解释器不仅会捕获 StopIteration 异常,还会把value 属性的值变成 yield from 表达式的值。
yield from x 表达式对 x 对象所做的第一件事是,调用 iter(x),从中获取迭代器。
因此, x 可以是任何可迭代的对象可是,如果 yield from 结构唯一的作用是替代产出值的嵌套 for 循环,这个结构很有可能不会添加到 Python 语言中。
yield from 的主要功能是打开双向通道,把最外层的调用方与最内层的子生成器连接起来,
这样二者可以直接发送和产出值,还可以直接传入异常,而不用在位于中间的协程中添加大量处理异常的样板代码。
有了这个结构,协程可以通过以前不可能的方式委托职责。
PEP 380 使用了一些专门的术语
#委派生成器
包含 yield from <iterable> 表达式的生成器函数。
#子生成器
从 yield from 表达式中 <iterable> 部分获取的生成器
委派生成器在 yield from 表达式处暂停时,调用方可以直接把数据发给子生成器,子生成器再把产出的值发给调用方。
子生成器返回之后,解释器会抛出
异常,并把返回值附加到异常对象上,此时委派生成器会恢复
二:示例
示例:使用 yield from 计算平均值并输出统计报告
# _*_ coding:utf-8 _*_
__author__ = "lixiang"
from collections import namedtuple
Result = namedtuple('Result', 'count average') # 子生成器
def averager(): #
total = 0.0
count = 0
average = None
while True:
term = yield #
if term is None:#
break
total += term
count += 1
average = total/count
return Result(count, average) # # 委派生成器
def grouper(results, key): #
while True: #
results[key] = yield from averager() # # 客户端代码,即调用方
def main(data): #
results = {}
for key, values in data.items():
group = grouper(results, key) #
next(group) #
for value in values:
group.send(value) #
group.send(None) # 重要!#12
# print(results) # 如果要调试,去掉注释
report(results)
# 输出报告
def report(results):
for key, result in sorted(results.items()):
group, unit = key.split(';')
print('{:2} {:5} averaging {:.2f}{}'.format(result.count, group, result.average, unit)) data = {
'girls;kg':
[40.9, 38.5, 44.3, 42.2, 45.2, 41.7, 44.5, 38.0, 40.6, 44.5],
'girls;m':
[1.6, 1.51, 1.4, 1.3, 1.41, 1.39, 1.33, 1.46, 1.45, 1.43],
'boys;kg':
[39.0, 40.8, 43.2, 40.8, 43.1, 38.6, 41.4, 40.6, 36.3],
'boys;m':
[1.38, 1.5, 1.32, 1.25, 1.37, 1.48, 1.25, 1.49, 1.46],
}
if __name__ == '__main__':
main(data) """
❶ 的 averager 协程一样。这里作为子生成器使用。
❷ main 函数中的客户代码发送的各个值绑定到这里的 term 变量上。
❸ 至关重要的终止条件。如果不这么做,使用 yield from 调用这个协程的生成器会永
远阻塞。
❹ 返回的 Result 会成为 grouper 函数中 yield from 表达式的值。
❺ grouper 是委派生成器。
❻ 这个循环每次迭代时会新建一个 averager 实例;每个实例都是作为协程使用的生成
器对象。
❼ grouper 发送的每个值都会经由 yield from 处理,通过管道传给 averager 实
例。 grouper 会在 yield from 表达式处暂停,等待 averager 实例处理客户端发来的
值。 averager 实例运行完毕后,返回的值绑定到 results[key] 上。 while 循环会不断
创建 averager 实例,处理更多的值。
❽ main 函数是客户端代码,用 PEP 380 定义的术语来说,是“调用方”。这是驱动一切的
函数。
❾ group 是调用 grouper 函数得到的生成器对象,传给 grouper 函数的第一个参数是
results,用于收集结果;第二个参数是某个键。 group 作为协程使用。
❿ 预激 group 协程。
⓫ 把各个 value 传给 grouper。传入的值最终到达 averager 函数中 term = yield 那
一行; grouper 永远不知道传入的值是什么。
⓬ 把 None 传入 grouper,导致当前的 averager 实例终止,也让 grouper 继续运行,
再创建一个 averager 实例,处理下一组值。
5)协程二(yeild from)的更多相关文章
- Python自动化开发 -进程、线程和协程(二)
本节内容 一.线程进程介绍 二. 线程 1.线程基本使用 (Threading) 2.线程锁(Lock.RLock) 3.信号量(Semaphore) 4.事件(event) 5.条件(Conditi ...
- Python异步IO之协程(二):使用asyncio的不同方法实现协程
引言:在上一章中我们介绍了从yield from的来源到async的使用,并在最后以asyncio.wait()方法实现协程,下面我们通过不同控制结构来实现协程,让我们一起来看看他们的不同作用吧- 在 ...
- python协程和yeild
python多线程其实在操作系统级别是进程,因为在执行时,默认加了一个全局解释器锁(GIL),python的多线程,本质还是串行的,无法利用多核的优势:在java和C# 中,多线程是并发的,可以充分利 ...
- Kotlin Coroutine(协程): 二、初识协程
@ 目录 前言 一.初识协程 1.runBlocking: 阻塞协程 2.launch: 创建协程 3.Job 4.coroutineScope 5.协程取消 6.协程超时 7.async 并行任务 ...
- 011-Python-进程、线程于协程
1.进程与线程 进程: 一个程序要运行时所需的所有资源的集合: 一个进程至少需要一个线程,这个线程称为主线程,一个进程里可以包含多个线程: cpu 核数越多,代表着你可以真正并发的线程越多2个进程之间 ...
- Golang 协程调度
一.线程模型 N:1模型,N个用户空间线程在1个内核空间线程上运行.优势是上下文切换非常快但是无法利用多核系统的优点. 1:1模型,1个内核空间线程运行一个用户空间线程.这种充分利用了多核系统的优势但 ...
- Python_oldboy_自动化运维之路_线程,进程,协程(十一)
本节内容: 线程 进程 协程 IO多路复用 自定义异步非阻塞的框架 线程和进程的介绍: 举个例子,拿甄嬛传举列线程和进程的关系: 总结:1.工作最小单元是线程,进程说白了就是提供资源的 2.一个应用程 ...
- (17) go 协程管道
一.协程 二.管道
- python协程详解
目录 python协程详解 一.什么是协程 二.了解协程的过程 1.yield工作原理 2.预激协程的装饰器 3.终止协程和异常处理 4.让协程返回值 5.yield from的使用 6.yield ...
随机推荐
- JS获得元素相对位置坐标getBoundingClientRect()
getBoundingClientRect用于获取某个元素相对于视窗的位置集合.集合中有top, right, bottom, left等属性. 1.语法:这个方法没有参数. rectObject = ...
- 学习 vue 源码 -- 响应式原理
概述 由于刚开始学习 vue 源码,而且水平有限,有理解或表述的不对的地方,还请不吝指教. vue 主要通过 Watcher.Dep 和 Observer 三个类来实现响应式视图.另外还有一个 sch ...
- Jenkins pipeline shared library
Jenkinsfile https://jenkins.io/doc/book/pipeline/jenkinsfile/ Jenkins Pipeline is a suite of plugins ...
- 三十九、Linux 线程——线程的同步和互斥
39.1 概念 线程同步 是一个宏观概念,在微观上包含线程的相互排斥和线程先后执行的约束问题 解决同步方式 条件变量 线程信号量 线程互斥 线程执行的相互排斥 解决互斥的方式 互斥锁 读写锁 线程信号 ...
- 利用PHP实现登录与注册功能以及使用PHP读取mysql数据库——以表格形式显示数据
登录界面 <body><form action="login1.php" method="post"><div>用户名:&l ...
- 牛客寒假算法基础集训营4 G(最小生成树)
题目链接 题目要求的是得到k种不同的元素,(题解)将每种类型视为一个点,跑一边克鲁斯卡尔即可. #include <set> #include <map> #include & ...
- python 中的列表List
一 定义:能装东西的东西 列表中装的数据是没有限制的, 大小基本上是够用的列表使用[]来表示. 在列表中每个元素与元素之间用逗号隔开(有索引和切片) 索引:每个元素对于一个单独索引号 切片, list ...
- mysql案例~关于linux服务器本身的优化问题
简介:mysql服务优化分为 1服务器本身的优化 2mysql本身的性能优化 今天咱们来讨论下服务器本身的优化性能 一 参数的优化简介 1 文件系统的选择 Linux 常用文件系统: ext3, ex ...
- linux 压缩解压缩命令
- sonar的安装以及使用
SonarQube是管理代码质量一个开放平台,可以快速的定位代码中潜在的或者明显的错误,下面将会介绍一下这个工具的安装.配置以及使用. 1. 简介 1. sonar是什么 Sonar是一个用于代码质 ...