当前位置: 首页 > news >正文

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 章 协程

从句法上看&#xff0c;协程与生成器类似&#xff0c;都是定义体中包含 yield 关键字的函数。可是&#xff0c;在协程中&#xff0c;yield通常出现在表达式的右边(例如&#xff0c;datum yield)&#xff0c;可以产出值&#xff0c;也可以不产出——如果 yield 关键字后面没有表…...

山东科技大学校历 代码分析 获得以前学期学年的老版校历

校历-山东科技大学网络安全与信息化办公室http://tech.sdust.edu.cn/wlfw/xl.htm JavaScript var studyStart new Date(2021, 8-1, 30);//8-1 -1没有意义&#xff0c;30代表30号&#xff0c;2021年8月30号开始这个学期 var commonWeeks 19;//这个学期有多少周 var s…...

第五章.与学习相关技巧—权重初始值(随机初始值,Xavier初始值,He初始值)

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

Linux进程间通信(管道)

进程间通信的目的 数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程 资源共享&#xff1a;多个进程之间共享同样的资源。 通知事件&#xff1a;一个进程需要向另一个或一组进程发送消息&#xff0c;通知它&#xff08;它们&#xff09;发生了某种事件&#xff08;如…...

写一个基于node.js的api后台管理系统(三)

创建登录页面 在项目目录下创建一个名为public的文件夹&#xff0c;并在其中创建一个HTML文件login.html。添加以下代码&#xff1a; <!DOCTYPE html> <html> <head><title>Login - Task Management</title> </head> <body><h1…...

【23种设计模式】行为型模式详细介绍(上)

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

PID控制算法进阶

关于PID控制算法基础概念在本文不再重复了&#xff0c;详情可参考&#xff1a;PID控制算法基础介绍 本文主要从PID算法代码实现&#xff0c;代码解析&#xff0c;理论进阶&#xff0c;PID调参等方向进行阐述。 目录位置式PID和增量式PID1.1 位置式PID1.2 增量式PID1.3 位置式和…...

嵌入式工程师有什么值得一看的网站和书籍吗?

原文直达&#xff1a; 嵌入式工程师有什么值得一看的网站和书籍吗&#xff1f; - CodeAllen的回答 - 知乎 https://www.zhihu.com/question/68423119/answer/2885623392 我是资深网站保存爱好者&#xff0c;浏览器分门别类存了应该有几百个网址&#xff0c;关于嵌入式的也有很…...

操作系统的四个特征

一、并发 并发&#xff1a;是指两个或多个事件在同一时间间隔内发生。这些事件宏观上是同时发生的&#xff0c;但微观上是交替发生的。 并行&#xff1a;指两个或多个事件在同一时刻同时发生。 操作系统的并发性指计算机系统中同时存在着多个运行的程序。操作系统和程序并发…...

Django框架之模型shell工具和查看MySQL数据库日志

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

电脑录屏怎样不录到外界声音?调整这一个开关,即可实现

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

无需登录复制网站文字的解决方案

大家好,我是爱编程的喵喵。双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&#xff1f;Reason for bias&varianceDropout is a kind of ensembleRec…...

ArkUI新能力,助力应用开发更便捷

ArkUI是一套构建分布式应用的声明式UI开发框架。它具备简洁自然的UI信息语法、丰富的UI组件、多维的状态管理&#xff0c;以及实时界面预览等相关能力&#xff0c;帮助您提升应用开发效率&#xff0c;并能在多种设备上实现生动而流畅的用户体验。随着HarmonyOS 3.1版本的发布&a…...

vue面试题大全

Vue面试题大全一.vue的基本原理二.双向数据绑定的原理三.使用object.defineProperty()来进行数据劫持有什么缺点&#xff1f;一.vue的基本原理 当一个vue实例创建的时候&#xff0c;vue会遍历data中的属性&#xff0c;用object.defineProperty&#xff0c;将它们转为getter/se…...

P1307 [NOIP2011 普及组] 数字反转

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

【服务器数据恢复】NetApp存储无法访问的数据恢复案例

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

(考研湖科大教书匠计算机网络)第四章网络层-第三节2:分类编址的IPv4地址

获取pdf&#xff1a;密码7281专栏目录首页&#xff1a;【专栏必读】考研湖科大教书匠计算机网络笔记导航 文章目录一&#xff1a;分类IP地址概述二&#xff1a;各类地址详解&#xff08;1&#xff09;A类地址&#xff08;2&#xff09;B类地址&#xff08;3&#xff09;C类地址…...

Allegro移动器件时附带的孔和线被同步更改的原因和解决办法

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

工程监测多通道振弦模拟信号采集仪VTN参数修改

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

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘

美国西海岸的夏天&#xff0c;再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至&#xff0c;这不仅是开发者的盛宴&#xff0c;更是全球数亿苹果用户翘首以盼的科技春晚。今年&#xff0c;苹果依旧为我们带来了全家桶式的系统更新&#xff0c;包括 iOS 26、iPadOS 26…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

Python如何给视频添加音频和字幕

在Python中&#xff0c;给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加&#xff0c;包括必要的代码示例和详细解释。 环境准备 在开始之前&#xff0c;需要安装以下Python库&#xff1a;…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...