Fluent Python 笔记 第 16 章 协程
从句法上看,协程与生成器类似,都是定义体中包含 yield 关键字的函数。可是,在协程中,yield通常出现在表达式的右边(例如,datum = yield),可以产出值,也可以不产出——如果 yield 关键字后面没有表达式,那么生成器产出 None。协程可能会从调用方接收数据,不过调用方把数据提供给协程使用的是 .send(datum) 方法,而不是 next(…) 函数。通常,调用方会把值推送给协程。
yield 关键字甚至还可以不接收或传出数据。不管数据如何流动,yield 都是一种流程控制 工具,使用它可以实现协作式多任务:协程可以把控制器让步给中心调度程序,从而激活 其他的协程。
从根本上把 yield 视作控制流程的方式,这样就好理解协程了。
16.1 生成器如何进化成协程
16.2 用作协程的生成器的基本行为
def simple_coroutine():print('-> coroutine started')x = yieldprint('-> coroutine received:', x)>>> my_coro = simple_coroutine()
>>> my_coro
<generator object simple_coroutine at 0x100c2be10>
>>> next(my_coro)
-> coroutine started
>>> my_coro.send(42)
-> coroutine received: 42
Traceback (most recent call last):...StopIteration
与创建生成器的方式一样,调用函数得到生成器对象。
四个状态:
‘GEN_CREATED’
等待开始执行。
‘GEN_RUNNING’
解释器正在执行。只有在多线程应用中才能看到这个状态。此外,生成器对象在自己身上调用 getgeneratorstate 函数也行,不过这样做没什么用。
‘GEN_SUSPENDED’
在 yield 表达式处暂停。
‘GEN_CLOSED’
执行结束。
始终要调用 next(my_coro) 激活协程——也可以调用 my_coro.send(None),效果一样。
16.3 示例:使用协程计算移动平均值
def averager():total = 0.0count = 0 average = None while True:term = yield averagetotal += termcount += 1average = total/count>>> coro_avg = averager()
>>> next(coro_avg)
>>> coro_avg.send(10)
10.0
>>> coro_avg.send(30)
20.0
>>> coro_avg.send(5)
15.0
先输出再等待输入。
16.4 预激协程的装饰器
from functools import wrapsdef coroutine(func):
"""装饰器:向前执行到第一个`yield`表达式,预激`func`"""@wraps(func)def primer(*args,**kwargs):gen = func(*args,**kwargs)next(gen)return genreturn primer
使用yield from
句法(参见16.7节)调用协程时,会自动预激。
16.5 终止协程和异常处理
exc_coro.close()
exc_coro.throw(DemoException)
class DemoException(Exception):
"""为这次演示定义的异常类型。"""
def demo_finally():print('-> coroutine started')try:while True:try:x = yieldexcept DemoException:print('*** DemoException handled. Continuing...')else:print('-> coroutine received: {!r}'.format(x))finally:print('-> coroutine ending')
16.6 让协程返回值
...
return Result(count, average)try:coro_avg.send(None)
except StopIteration as exc:result = exc.value
16.7 使用 yield from
yield from x
表达式对x对象所做的第一件事是,调用iter(x)
,从中获取迭代器。
yield from
的主要功能是打开双向通道,把最外层的调用方与最内层的子生成器连接起来。
委派生成器
包含 yield from <iterable>
表达式的生成器函数。
子生成器
从 yield from
表达式中 <iterable>
部分获取的生成器。
调用方
指代调用委派生成器的客户端代码。
示例用法:
# 子生成器
def averager():total = 0.0count = 0average = Nonewhile True:term = yieldif term is None:breaktotal += termcount += 1average = total/countreturn 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) # 重要!# print(results) # 如果要调试,去掉注释report(results)
如果子生成器不终止,委派生成器会在 yield from
表达式处永远暂停。
16.8 yield from 的意义
16.9 使用案例:使用协程做离散事件仿真
相关文章:
Fluent Python 笔记 第 16 章 协程
从句法上看,协程与生成器类似,都是定义体中包含 yield 关键字的函数。可是,在协程中,yield通常出现在表达式的右边(例如,datum yield),可以产出值,也可以不产出——如果 yield 关键字后面没有表…...
山东科技大学校历 代码分析 获得以前学期学年的老版校历
校历-山东科技大学网络安全与信息化办公室http://tech.sdust.edu.cn/wlfw/xl.htm JavaScript var studyStart new Date(2021, 8-1, 30);//8-1 -1没有意义,30代表30号,2021年8月30号开始这个学期 var commonWeeks 19;//这个学期有多少周 var s…...

第五章.与学习相关技巧—权重初始值(随机初始值,Xavier初始值,He初始值)
第五章.与学习相关技巧 5.2 权重初始值 本节将介绍权重初始值的推荐值,并通过实验确认神经网络的学习是否会快速进行。 1.权值衰减 权值衰减就是一种以减少权重参数的值为目的进行学习的方法,通过减少权重参数值来抑制过拟合的情况发生。 2.权重初始值不…...

Linux进程间通信(管道)
进程间通信的目的 数据传输:一个进程需要将它的数据发送给另一个进程 资源共享:多个进程之间共享同样的资源。 通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如…...
写一个基于node.js的api后台管理系统(三)
创建登录页面 在项目目录下创建一个名为public的文件夹,并在其中创建一个HTML文件login.html。添加以下代码: <!DOCTYPE html> <html> <head><title>Login - Task Management</title> </head> <body><h1…...

【23种设计模式】行为型模式详细介绍(上)
前言 本文为 【23种设计模式】行为型模式 相关内容介绍,下边将对访问者模式,模板模式,策略模式,状态模式,观察者模式,备忘录模式,中介者模式,迭代器模式,解释器模式&…...

PID控制算法进阶
关于PID控制算法基础概念在本文不再重复了,详情可参考:PID控制算法基础介绍 本文主要从PID算法代码实现,代码解析,理论进阶,PID调参等方向进行阐述。 目录位置式PID和增量式PID1.1 位置式PID1.2 增量式PID1.3 位置式和…...
嵌入式工程师有什么值得一看的网站和书籍吗?
原文直达: 嵌入式工程师有什么值得一看的网站和书籍吗? - CodeAllen的回答 - 知乎 https://www.zhihu.com/question/68423119/answer/2885623392 我是资深网站保存爱好者,浏览器分门别类存了应该有几百个网址,关于嵌入式的也有很…...
操作系统的四个特征
一、并发 并发:是指两个或多个事件在同一时间间隔内发生。这些事件宏观上是同时发生的,但微观上是交替发生的。 并行:指两个或多个事件在同一时刻同时发生。 操作系统的并发性指计算机系统中同时存在着多个运行的程序。操作系统和程序并发…...

Django框架之模型shell工具和查看MySQL数据库日志
shell工具和查看MySQL数据库日志 1 shell工具 Django的manage工具提供了shell命令,帮助我们配置好当前工程的运行环境(如连接好数据库等),以便可以直接在终端中执行测试python语句。 通过如下命令进入shell python manage.py …...

电脑录屏怎样不录到外界声音?调整这一个开关,即可实现
有很多小伙伴希望自己电脑录屏的时候,不要录制自己的声音,而是通过后期配音的方式完成视频创作。电脑录屏怎样不录到外界声音?其实只需要调整这一个开关,就能实现不录外界声音,一起来看看吧。 不录外界声音1…...

无需登录复制网站文字的解决方案
大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。喜欢通过博客创作的方式对所学的知识进行总结与归纳,不仅形成深入且独到的理…...

ccc-Tips for Deep Learning-李宏毅(8)
文章目录Recipe of Deep LearningGood Results on Training DataNew activation functionAdaptive Learning RateGood Results on Testing DataEarly StoppingRegularizationDropoutwhy Dropout work?Reason for bias&varianceDropout is a kind of ensembleRec…...

ArkUI新能力,助力应用开发更便捷
ArkUI是一套构建分布式应用的声明式UI开发框架。它具备简洁自然的UI信息语法、丰富的UI组件、多维的状态管理,以及实时界面预览等相关能力,帮助您提升应用开发效率,并能在多种设备上实现生动而流畅的用户体验。随着HarmonyOS 3.1版本的发布&a…...
vue面试题大全
Vue面试题大全一.vue的基本原理二.双向数据绑定的原理三.使用object.defineProperty()来进行数据劫持有什么缺点?一.vue的基本原理 当一个vue实例创建的时候,vue会遍历data中的属性,用object.defineProperty,将它们转为getter/se…...

P1307 [NOIP2011 普及组] 数字反转
[NOIP2011 普及组] 数字反转 题目描述 给定一个整数 NNN,请将该数各个位上数字反转得到一个新数。新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零(参见样例 2)。 输入…...

【服务器数据恢复】NetApp存储无法访问的数据恢复案例
服务器数据恢复环境: NetApp某型号存储; 配备SAS硬盘,该硬盘520字节一个扇区; 所有的lun映射到小型机使用,存放Oracle数据库文件,采用ASM裸设备存储方式。 服务器故障: 管理员误操作删除NetApp…...

(考研湖科大教书匠计算机网络)第四章网络层-第三节2:分类编址的IPv4地址
获取pdf:密码7281专栏目录首页:【专栏必读】考研湖科大教书匠计算机网络笔记导航 文章目录一:分类IP地址概述二:各类地址详解(1)A类地址(2)B类地址(3)C类地址…...

Allegro移动器件时附带的孔和线被同步更改的原因和解决办法
Allegro移动器件时附带的孔和线被同步更改的原因和解决办法 用Allegro做PCB设计的时候,移动器件的时候,会出现附带的孔和线也会被同步更改,有时并不是期望的效果,如下图 Allegro其实将这个功能关闭即可,具体操作如下 选择Edit点击Move命令...

工程监测多通道振弦模拟信号采集仪VTN参数修改
工程监测多通道振弦模拟信号采集仪VTN参数修改 1 使用按键修改参数 使用按键修改某个参数的方法如下: (1)在系统参数查看页面(PXX 页面),按【SWITCH】或【SETTING】按键切换到要修改的参数项。 (…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...

springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...

【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...