Coroutine 终止协程和异常处理
终止协程和异常处理
协程中未处理的异常会向上冒泡,传给 next 函数或 send 方法的调用方(即触发协程的对象)
终止协程的一种方式:发送某个哨符值,让协程退出。内置的 None 和
Ellipsis 等常量经常用作哨符值。 Ellipsis 的优点是,数据流中不太常有这个值。有人把
StopIteration 类(类本身,而不是实例,也不抛出)作为哨符值;也就是说,
是像这样使用的: my_coro.send(StopIteration)。从 Python 2.5 开始,客户代码可以在
生成器对象上调用两个方法,显式地把异常发给协程。这两个方法是 throw 和 close。
generator.throw(exc_type[, exc_value[, traceback]])
致使生成器在暂停的 yield 表达式处抛出指定的异常。如果生成器处理了抛出的异
常,代码会向前执行到下一个 yield 表达式,而产出的值会成为调用 generator.throw
方法得到的返回值。如果生成器没有处理抛出的异常,异常会向上冒泡,传到调用方的上
下文中。
generator.close()
致使生成器在暂停的 yield 表达式处抛出 GeneratorExit 异常。如果生成器没有处
理这个异常,或者抛出了 StopIteration 异常(通常是指运行到结尾),调用方不会报
错。如果收到 GeneratorExit 异常,生成器一定不能产出值,否则解释器会抛出
RuntimeError 异常。生成器抛出的其他异常会向上冒泡,传给调用方。
让协程返回值
from collections import namedtuple
Results = namedtuple('Result', 'count average')
def coro_average_return():
total = 0.0
count = 0
average = None
while 1:
term = yield # 这一版不产出值
if term is None: # 发送 None 会终止循环,导致协程结束,返回结果。一如既往,生成器对象会抛出 StopIteration 异常。异常对象的 value 属性保存着返回的值。
break
total += term
count += 1
average = total / count
return Results(count, average)
coro4 = coro_average_return()
next(coro4)
coro4.send(10)
coro4.send(15)
coro4.send(3)
try:
coro4.send(None)
except StopIteration as exe:
result = exe.value # return 表达式的值会偷偷传给调用方,赋值给 StopIteration 异常的一个属性。
# 这样做有点不合常理,但是能保留生成器对象的常规行为——耗尽时抛出 StopIteration 异常。
获取协程的返回值虽然要绕个圈子,但这是 PEP 380 定义的方式,当我们意识到这一点之
后就说得通了: yield from 结构会在内部自动捕获 StopIteration 异常。这种处理方
式与 for 循环处理 StopIteration 异常的方式一样:循环机制通过用户易于理解的方式
处理异常。对 yield from 结构来说,解释器不仅会捕获 StopIteration 异常,还会把
value 属性的值变成 yield from 表达式的值。但是,我们无法在控制台中使用交互的方
式测试这种行为,因为在函数外部使用 yield from(以及 yield)会导致句法出错。
Coroutine 终止协程和异常处理的更多相关文章
- C#中的yield return与Unity中的Coroutine(协程)(下)
Unity中的Coroutine(协程) 估计熟悉Unity的人看过或者用过StartCoroutine() 假设我们在场景中有一个UGUI组件, Image: 将以下代码绑定到Image using ...
- Boost.Coroutine2:学习使用Coroutine(协程)
function(函数)routine(例程)coroutine (协程) 函数,例程以及协程都是指一系列的操作的集合. 函数(有返回值)以及例程(没有返回值)也被称作subroutine(子例程), ...
- Lua基础之coroutine(协程)
概括:1.创建协程2.coroutine的函数3.coroutine的基本流程4.yield对coroutine流程的干预5.resume, function()以及yield之间的参数传递和返回值传 ...
- Routine Subroutine Coroutine 子程序 协程
https://en.wikipedia.org/wiki/Subroutine In computer programming, a subroutine is a sequence of prog ...
- Routine Subroutine Coroutine 子程序 协程 子例程
https://en.wikipedia.org/wiki/Subroutine In computer programming, a subroutine is a sequence of prog ...
- C#中的yield return与Unity中的Coroutine(协程)(上)
C#中的yield return C#语法中有个特别的关键字yield, 它是干什么用的呢? 来看看专业的解释: yield 是在迭代器块中用于向枚举数对象提供值或发出迭代结束信号.它的形式为下列之一 ...
- Python协程深入理解
从语法上来看,协程和生成器类似,都是定义体中包含yield关键字的函数.yield在协程中的用法: 在协程中yield通常出现在表达式的右边,例如:datum = yield,可以产出值,也可以不产出 ...
- 【Python】【容器 | 迭代对象 | 迭代器 | 生成器 | 生成器表达式 | 协程 | 期物 | 任务】
Python 的 asyncio 类似于 C++ 的 Boost.Asio. 所谓「异步 IO」,就是你发起一个 IO 操作,却不用等它结束,你可以继续做其他事情,当它结束时,你会得到通知. Asyn ...
- 流畅的python第十六章协程学习记录
从句法上看,协程与生成器类似,都是定义体中包含 yield 关键字的函数.可是,在协程中,yield 通常出现在表达式的右边(例如,datum = yield),可以产出值,也可以不产出——如果 yi ...
随机推荐
- 【转】Java集合框架面试问题集锦
Java集合框架(例如基本的数据结构)里包含了最常见的Java常见面试问题.很好地理解集合框架,可以帮助你理解和利用Java的一些高级特性.下面是面试Java核心技术的一些很实用的问题. Q:最常见的 ...
- Linux普通用户如何获取root权限 sudo -i
从下图中可以知道,xiaolai这个用户连接到服务器后它没有权限,更新代码都更新不了 那么我们作为一个普通用户要获取管理员权限,怎么办呢? 输入 sudo -i 然后再输入普通用户的这个密码 获取成功 ...
- Spring Boot2 系列教程 (十三) | 整合 MyBatis (XML 版)
前言 如题,今天介绍 SpringBoot 与 Mybatis 的整合以及 Mybatis 的使用,之前介绍过了 SpringBoot 整合MyBatis 注解版的使用,上一篇介绍过 MyBatis ...
- java架构之路(多线程)JUC并发编程之Semaphore信号量、CountDownLatch、CyclicBarrier栅栏、Executors线程池
上期回顾: 上次博客我们主要说了我们juc并发包下面的ReetrantLock的一些简单使用和底层的原理,是如何实现公平锁.非公平锁的.内部的双向链表到底是什么意思,prev和next到底是什么,为什 ...
- Linux下安装JDK 1.8
前言 JDK是 JAVA 的软件开发工具包,如果要使用JAVA来进行开发,或者部署基于其开发的应用,那么就需要安装JDK.本次将在Linux下安装JDK及配置环境. 本人环境:CentOS 7.3 6 ...
- PythonI/O进阶学习笔记_11.python的多进程
content: 1. 为什么要多进程编程?和多线程有什么区别? 2. python 多进程编程 3. 进程间通信 ======================================= ...
- [洛谷P3254] [网络流24题] 圆桌游戏
Description 假设有来自m 个不同单位的代表参加一次国际会议.每个单位的代表数分别为ri (i =1,2,--,m). 会议餐厅共有n 张餐桌,每张餐桌可容纳ci (i =1,2,--,n) ...
- HGE_improve 0.1发布
HGE_improve 0.1发布 写了1个月了,虽然还有很多很多缺陷,但丑姑娘也是要见公婆的. 主要修改如下: 1.全UNICODE化 2.增加切片动画 3.增加骨骼动画 4.增加MyGUI接口 5 ...
- Linux程序守护脚本
不废话,直接上脚本,[]注释的下发语句需要按需替换: #!/usr/bin/env bash PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/us ...
- 开源项目SMSS发开指南(四)——SSL/TLS加密通信详解
本文将详细介绍如何在Java端.C++端和NodeJs端实现基于SSL/TLS的加密通信,重点分析Java端利用SocketChannel和SSLEngine从握手到数据发送/接收的完整过程.本文也涵 ...