一: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. 使用jQuery插件时避免重复引入jquery.js文件

    当一个页面使用多个jQuery插件时,需要避免重复引入jquery.js文件,因为后面映入的jQuery.js文件中定义的jQuery对象会覆盖掉前面的jQuery对象,导致之前定义的jQuery插件 ...

  2. Listener 快速开始

    [SessionListener] @WebListenerpublic class SessionListener implements HttpSessionListener,HttpSessio ...

  3. mysql插入记录INSERT与多表更新

    1.第一种:INSERT [INTO] tbl_name[ (col_name, ... ) ]  {VALUES | VALUE}({expr |default}, ... ), (...), .. ...

  4. Andrew NG 机器学习编程作业5 Octave

    问题描述:根据水库中蓄水标线(water level) 使用正则化的线性回归模型预 水流量(water flowing out of dam),然后 debug 学习算法 以及 讨论偏差和方差对 该线 ...

  5. bus实现兄弟组件传值

    传递的地方:两个组件都要引入这个公共的bus中转函数 Bus.js文件相当于一个公共的对象: 传递的文件中写入这个方法: 兄弟组件通过点击事件输出参数,需要的组件来接收传递过来的参数:

  6. 2.4 if-else

    if-else 想一想:在使用if的时候,它只能做到满足条件时要做的事情.那万一需要在不满足条件的时候,做某些事,该怎么办呢? 答:使用 if-else <1>if-else的使用格式 i ...

  7. PHP7语法知识(一):语言基础

    一.数据类型 1.字符串: 2.整形: var_dump函数:返回变量的数据类型和值. 3.浮点型: 4.布尔型: 5.数组: 6.对象: 7.NULL值 二.运算符 1.算术运算符: 2.递增递减运 ...

  8. python 多线程小方法

    import time from multiprocessing import Process, Lock, JoinableQueue from multiprocessing import Sem ...

  9. angular-file-upload 项目实践踩坑

    API文档: https://github.com/nervgh/angular-file-upload/wiki/Module-API 过程中得到昊哥的鼎力帮助,感谢. 需求如下,分别选择多个文件, ...

  10. B - Tree Rotations HYSBZ - 2212 (线段树合并)

    题目链接:https://cn.vjudge.net/contest/287725#problem/B 题目大意:现在有一棵二叉树,所有非叶子节点都有两个孩子.在每个叶子节点上有一个权值(有n个叶子节 ...