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

  1. Python自动化开发 -进程、线程和协程(二)

    本节内容 一.线程进程介绍 二. 线程 1.线程基本使用 (Threading) 2.线程锁(Lock.RLock) 3.信号量(Semaphore) 4.事件(event) 5.条件(Conditi ...

  2. Python异步IO之协程(二):使用asyncio的不同方法实现协程

    引言:在上一章中我们介绍了从yield from的来源到async的使用,并在最后以asyncio.wait()方法实现协程,下面我们通过不同控制结构来实现协程,让我们一起来看看他们的不同作用吧- 在 ...

  3. python协程和yeild

    python多线程其实在操作系统级别是进程,因为在执行时,默认加了一个全局解释器锁(GIL),python的多线程,本质还是串行的,无法利用多核的优势:在java和C# 中,多线程是并发的,可以充分利 ...

  4. Kotlin Coroutine(协程): 二、初识协程

    @ 目录 前言 一.初识协程 1.runBlocking: 阻塞协程 2.launch: 创建协程 3.Job 4.coroutineScope 5.协程取消 6.协程超时 7.async 并行任务 ...

  5. 011-Python-进程、线程于协程

    1.进程与线程 进程: 一个程序要运行时所需的所有资源的集合: 一个进程至少需要一个线程,这个线程称为主线程,一个进程里可以包含多个线程: cpu 核数越多,代表着你可以真正并发的线程越多2个进程之间 ...

  6. Golang 协程调度

    一.线程模型 N:1模型,N个用户空间线程在1个内核空间线程上运行.优势是上下文切换非常快但是无法利用多核系统的优点. 1:1模型,1个内核空间线程运行一个用户空间线程.这种充分利用了多核系统的优势但 ...

  7. Python_oldboy_自动化运维之路_线程,进程,协程(十一)

    本节内容: 线程 进程 协程 IO多路复用 自定义异步非阻塞的框架 线程和进程的介绍: 举个例子,拿甄嬛传举列线程和进程的关系: 总结:1.工作最小单元是线程,进程说白了就是提供资源的 2.一个应用程 ...

  8. (17) go 协程管道

    一.协程 二.管道

  9. python协程详解

    目录 python协程详解 一.什么是协程 二.了解协程的过程 1.yield工作原理 2.预激协程的装饰器 3.终止协程和异常处理 4.让协程返回值 5.yield from的使用 6.yield ...

随机推荐

  1. JS获得元素相对位置坐标getBoundingClientRect()

    getBoundingClientRect用于获取某个元素相对于视窗的位置集合.集合中有top, right, bottom, left等属性. 1.语法:这个方法没有参数. rectObject = ...

  2. 学习 vue 源码 -- 响应式原理

    概述 由于刚开始学习 vue 源码,而且水平有限,有理解或表述的不对的地方,还请不吝指教. vue 主要通过 Watcher.Dep 和 Observer 三个类来实现响应式视图.另外还有一个 sch ...

  3. Jenkins pipeline shared library

    Jenkinsfile https://jenkins.io/doc/book/pipeline/jenkinsfile/ Jenkins Pipeline is a suite of plugins ...

  4. 三十九、Linux 线程——线程的同步和互斥

    39.1 概念 线程同步 是一个宏观概念,在微观上包含线程的相互排斥和线程先后执行的约束问题 解决同步方式 条件变量 线程信号量 线程互斥 线程执行的相互排斥 解决互斥的方式 互斥锁 读写锁 线程信号 ...

  5. 利用PHP实现登录与注册功能以及使用PHP读取mysql数据库——以表格形式显示数据

    登录界面 <body><form action="login1.php" method="post"><div>用户名:&l ...

  6. 牛客寒假算法基础集训营4 G(最小生成树)

    题目链接 题目要求的是得到k种不同的元素,(题解)将每种类型视为一个点,跑一边克鲁斯卡尔即可. #include <set> #include <map> #include & ...

  7. python 中的列表List

    一 定义:能装东西的东西 列表中装的数据是没有限制的, 大小基本上是够用的列表使用[]来表示. 在列表中每个元素与元素之间用逗号隔开(有索引和切片) 索引:每个元素对于一个单独索引号 切片, list ...

  8. mysql案例~关于linux服务器本身的优化问题

    简介:mysql服务优化分为 1服务器本身的优化 2mysql本身的性能优化 今天咱们来讨论下服务器本身的优化性能 一 参数的优化简介 1 文件系统的选择 Linux 常用文件系统: ext3, ex ...

  9. linux 压缩解压缩命令

  10. sonar的安装以及使用

    SonarQube是管理代码质量一个开放平台,可以快速的定位代码中潜在的或者明显的错误,下面将会介绍一下这个工具的安装.配置以及使用. 1. 简介 1.  sonar是什么 Sonar是一个用于代码质 ...