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

【python 生成器 面试必备】yield关键字,协程必知必会系列文章--自己控制程序调度,体验做上帝的感觉 1

python生成器系列文章目录

第一章 yield — Python (Part I)


文章目录

  • python生成器系列文章目录
  • 前言
  • 1. Generator Function 生成器函数
  • 2.并发和并行,抢占式和协作式
    • 2.Let’s implement Producer/Consumer pattern using subroutine:
  • 生成器的状态 generator’s states


前言

ref:https://medium.com/analytics-vidhya/yield-python-part-i-4dbfe914ad2d
这个老哥把yield讲清楚了,我来学习并且记录一下。


偶尔遇到Yield关键字时,它看起来相当神秘。这里,我们通过查看生成器如何使用yield获取值或将控制权返回给调用者来揭示yield所做的工作。我们也在看生成器generator的不同状态。让我们开始吧。

1. Generator Function 生成器函数

一个函数用了yield表达式后被称为生成器函数。

def happy_birthday_song(name='Eric'):yield "Happy Birthday to you"yield "Happy Birthday to you"yield f"Happy Birthday dear {name}"yield "Happy Birthday to you"
birthday_song_gen = happy_birthday_song() # generator creation
print(next(birthday_song_gen)) # prints first yield's value

birthday_song_gen 作为Generator被创建在第七行,相应的,生成器generator的执行通过调用next();
我们获得了yield的1个输出因为仅仅调用了一次next,接着generator是在suspend state(暂停/挂起状态),当另一个next()调用的时候,会激活执行并且返回第二个yield的值。像任何迭代器iterator一样,生成器将会exhausted 当stopIteration is encountered.

def happy_birthday_song(name='Eric'):yield "Happy Birthday to you"yield "Happy Birthday to you"yield f"Happy Birthday dear {name}"yield "Happy Birthday to you"birthday_song_gen = happy_birthday_song() # generator creation
print(next(birthday_song_gen)) # prints first yield's value# print rest of the yield's value
try:while True:print(next(birthday_song_gen))
except StopIteration:print('exhausted...')

2.并发和并行,抢占式和协作式

在这里插入图片描述
在这里插入图片描述
Cooperative multitasking is completely controlled by developer. Coroutine (Cooperative routine) is an example of cooperative multitasking.

Preemptive multitasking is not controlled by developer and have some sort of scheduler involved.

One of the ways to create coroutine in Python is generator.
在python中一种产生协程的做法是generator 生成器。

global 表示将变量声明为全局变量
nonlocal 表示将变量声明为外层变量(外层函数的局部变量,而且不能是全局变量)

def average():count = 0sum = 0def inner(value):nonlocal countnonlocal sumcount += 1sum += valuereturn sum/countreturn innerdef running_average(iterable):avg = average()for value in iterable:running_average = avg(value):print(running_average)
iterable = [1,2,3,4,5]
running_average(iterable)

输出:
在这里插入图片描述

The program control flow looks like this:
这个图要好好理解一下:
在这里插入图片描述

2.Let’s implement Producer/Consumer pattern using subroutine:

from collections import dequedef produce_element(dq, n):print('\nIn producer ...\n')for i in range(n):dq.appendleft(i)print(f'appended {i}')# if deque is full, return the control back to `coordinator`if len(dq) == dq.maxlen:yielddef consume_element(dq):print('\nIn consumer...\n')while True:while len(dq) > 0:item = dq.pop()print(f'popped {item}')# once deque is empty, return the control back to `coordinator`yielddef coordinator():dq = deque(maxlen=2)# instantiate producer and consumer generatorproducer = produce_element(dq, 5)consumer = consume_element(dq)while True:try:# producer fills dequeprint('next producer...')next(producer)except StopIteration:breakfinally:# consumer empties dequeprint('next consumer...')next(consumer)if __name__ == '__main__':coordinator() 

output looks like this:

C:\Users\HP\.conda\envs\torch1.8\python.exe "C:\Program Files\JetBrains\PyCharm 2021.1.3\plugins\python\helpers\pydev\pydevd.py" --multiproc --qt-support=auto --client 127.0.0.1 --port 59586 --file D:/code/python_project/01-coroutine-py-mooc/8/demo_ccc.py
Connected to pydev debugger (build 211.7628.24)
next producer...In producer..next consumer ...In consumer... popped 0
popped 1
next producer...
next consumer ...
popped 2
popped 3
next producer...
next consumer ...Process finished with exit code -1

过程解析:
生产2个,消费2个,再生产两个,再消费两个,再生产一个,触发StopIteration,再转向finall 消费1个 整个进程结束。
详细的看英语:
What’s happening? Well, the following thing is happening:

  1. create a limited size deque , here size of 2

  2. coordinator creates an instance of producer generator and also mentioning how many elements it want to generate

  3. coordinator creates an instance of consumer generator

  4. producer runs until deque is filled and yields control back to caller

  5. consumer runs until deque is empty and yields control back to caller

Steps 3 and 4 are repeated until all elements the producer wanted to produce is complete. This coordination of consumer and producer is possible due to we being able to control state of a control flow.

生成器的状态 generator’s states

    from inspect import getgeneratorstatedef gen(flowers):for flower in flowers:print(f'Inside loop:{getgeneratorstate(flower_gen)}')yield flowerflower_gen = gen(['azalea', 'Forsythia', 'violas'])print(f"After generator creation:{getgeneratorstate(flower_gen)}\n")print('getting 1st flower')print("--==", next(flower_gen))print(f'After getting first flower: {getgeneratorstate(flower_gen)}\n')print(f'Get all flowers: {list(flower_gen)}\n')print(f'After getting all flowers: {getgeneratorstate(flower_gen)}')

输出:

C:\Users\HP\.conda\envs\torch1.8\python.exe D:/code/python_project/01-coroutine-py-mooc/8/demo_ccc.py
After generator creation:GEN_CREATEDgetting 1st flower
Inside loop:GEN_RUNNING
--== azalea
After getting first flower: GEN_SUSPENDEDInside loop:GEN_RUNNING
Inside loop:GEN_RUNNING
Get all flowers: ['Forsythia', 'violas']After getting all flowers: GEN_CLOSEDProcess finished with exit code 0

We have a handy getgeneratorstate method from inspect module that gives state of a generator. From the output, we see there are four different states:

  1. GEN_CREATED
  2. GEN_RUNNING
  3. GEN_SUSPENDED
  4. GEN_CLOSED
    GEN_CREATED is a state when we instantiate a generator. GEN_RUNNING is a state when a generator is yielding value. GEN_SUSPENDED is a state when a generator has yielded value. GEN_CLOSED is a state when a generator is exhausted.

In summary, yield is used by generators to produce value or give control back to caller and generator has 4 states.

My next article will be sending values to generators!
下一篇文章介绍如何传值到生成器

相关文章:

【python 生成器 面试必备】yield关键字,协程必知必会系列文章--自己控制程序调度,体验做上帝的感觉 1

python生成器系列文章目录 第一章 yield — Python (Part I) 文章目录 python生成器系列文章目录前言1. Generator Function 生成器函数2.并发和并行,抢占式和协作式2.Let’s implement Producer/Consumer pattern using subroutine: 生成器的状态 generator’s st…...

头哥实践平台之MapReduce基础实战

一. 第1关:成绩统计 编程要求 使用MapReduce计算班级每个学生的最好成绩,输入文件路径为/user/test/input,请将计算后的结果输出到/user/test/output/目录下。 先写命令行,如下: 一行就是一个命令 touch file01 echo Hello World Bye Wor…...

Linux基础知识——tmux和vim

Linux基础知识——tmux和vim 文章目录 Linux基础知识——tmux和vim一、tmux1. 功能2. 结构3. 操作 二、vim功能模式操作 一、tmux tmux配置:~/.tmux.conf修改为如下 set-option -g status-keys vi setw -g mode-keys visetw -g monitor-activity on# setw -g c0-cha…...

Java Web——TomcatWeb服务器

目录 1. 服务器概述 1.1. 服务器硬件 1.2. 服务器软件 2. Web服务器 2.1. Tomcat服务器 2.2. 简单的Web服务器使用 1. 服务器概述 服务器指的是网络环境下为客户机提供某种服务的专用计算机,服务器安装有网络操作系统和各种服务器的应用系统服务器的具有高速…...

Zookeeper 命令使用和数据说明

文章目录 一、概述二、命令使用2.1 登录 ZooKeeper2.2 ls 命令,查看目录树(节点)2.3 create 命令,创建节点2.4 delete 命令,删除节点2.5 set 命令,设置节点数据2.6 get 命令,获取节点数据 三、数…...

索尼RSV文件怎么恢复为MP4视频

索尼相机RSV是什么文件? 如果您的相机是索尼SONY A7S3,A7M4,FX3,FX3,FX6,或FX9等,有时录像会产生一个RSV文件,而没有MP4视频文件。RSV其实是MP4的前期文件,经我对RSV文件…...

pytorch-gpu(Anaconda3+cuda+cudnn)

文章目录 下载Anaconda3安装,看着点next就行比较懒所以自动添加path测试 cuda安装的时候不能改路径如果出现报错,关闭杀毒软件一直下一步就好取消勾选“CUDA”中的“Visual Studio Intergration”一直下一步即可测试安装成功 cudnn解压后将这三个文件夹复…...

解析数据洁净之道:BI中数据清理对见解的深远影响

本文由葡萄城技术团队发布。转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。 前言 随着数字化和信息化进程的不断发展,数据已经成为企业的一项不可或缺的重要资源。然而,这…...

efcore反向共工程,单元测试

1.安装efcore需要的nuget <PackageReference Include"Microsoft.EntityFrameworkCore" Version"6.0.24" /> <PackageReference Include"Microsoft.EntityFrameworkCore.SqlServer" Version"6.0.24" /> <PackageRefere…...

利用IP风险画像强化金融行业网络安全防御

在数字化时代&#xff0c;金融行业日益依赖互联网和技术创新&#xff0c;但这也使得金融机构成为网络攻击的主要目标。为了应对日益复杂的网络威胁&#xff0c;金融机构迫切需要采用先进的安全技术和工具。其中&#xff0c;IP风险画像技术成为提升网络安全的一项重要策略。 1.…...

1334. 阈值距离内邻居最少的城市

分析题目两点“阈值距离”、“邻居最少”。 “阈值距离”相当于定了个上界&#xff0c;求节点之间的最短距离。 “邻居最少”相当于能连接的点的数量。 求节点之间的最短距离有以下几种方法&#xff1a; 在这道题当中&#xff0c;n的范围是100以内&#xff0c;所以可以考虑O(n…...

Live800:客服行业的发展历程及未来前景

随着信息技术和互联网的高速发展&#xff0c;客服行业也在不断变革和发展。客服行业是一个服务型的行业&#xff0c;其发展历程也与人们对服务需求的变化密切相关。本文将介绍客服行业的发展历程和未来前景。 客服行业的发展历程 20世纪70年代&#xff0c;客服行业主要以电话服…...

exsi的安装和配置

直接虚拟真实机 vcent server 管理大量的exsi SXI原生架构模式的虚拟化技术&#xff0c;是不需要宿主操作系统的&#xff0c;它自己本身就是操作系统。因此&#xff0c;装ESXI的时候就等同于装操作系统&#xff0c;直接拿iso映像(光盘)装ESXI就可以了。 VMware vCente…...

基于springboot实现校园医疗保险管理系统【项目源码】

基于springboot实现校园医疗保险管理系统演示 系统开发平台 在线校园医疗保险系统中&#xff0c;Eclipse能给用户提供更多的方便&#xff0c;其特点一是方便学习&#xff0c;方便快捷&#xff1b;二是有非常大的信息储存量&#xff0c;主要功能是用在对数据库中查询和编程。其…...

Python 如何实现组合(Composite)设计模式?什么是组合设计模式?

什么是组合&#xff08;Composite&#xff09;设计模式&#xff1f; 组合&#xff08;Composite&#xff09;设计模式是一种结构型设计模式&#xff0c;它允许客户端使用单一对象和组合对象&#xff08;对象的组合形成树形结构&#xff09;同样的方式处理。这样&#xff0c;客…...

编辑器vim和编译器gcc/g++

目录 一、编辑器vim 1、概念 2、基本操作 1、进入vim 2、模式切换 3、命令行模式 4、插入模式 5、底行模式 6、vim 的配置 二、编译器gcc/g 1、概念 2、背景知识 3、gcc/g中的编译链接 1、预处理 2、编译 3、汇编 4、链接 4、函数库 1、静态库 2、动态库 一…...

linux 系统下文本编辑常用的命令

一、是什么 Vim是从 vi 发展出来的一个文本编辑器&#xff0c;代码补全、编译及错误跳转等方便编程的功能特别丰富&#xff0c;在程序员中被广泛使用。 简单的来说&#xff0c; vi 是老式的字处理器&#xff0c;不过功能已经很齐全了&#xff0c;但是还是有可以进步的地方 而…...

3D Gaussian Splatting文件的压缩【3D高斯泼溅】

在上一篇文章中&#xff0c;我开始研究高斯泼溅&#xff08;3DGS&#xff1a;3D Gaussian Splatting&#xff09;。 它的问题之一是数据集并不小。 渲染图看起来不错。 但“自行车”、“卡车”、“花园”数据集分别是一个 1.42GB、0.59GB、1.35GB 的 PLY 文件。 它们几乎按原样…...

Spring Boot 整合xxl-job实现分布式定时任务

xxl-job介绍 XXL-JOB是一个分布式任务调度平台&#xff0c;其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线&#xff0c;开箱即用。 xxl是xxl-job的开发者大众点评的许雪里名称的拼音开头。 设计思想 将调度行为抽象形成“调度…...

16.最接近的三数之和

​​题目来源&#xff1a; leetcode题目&#xff0c;网址&#xff1a;16. 最接近的三数之和 - 力扣&#xff08;LeetCode&#xff09; 解题思路&#xff1a; 对数组排序后&#xff0c;枚举第一个值&#xff0c;利用双指针在第一个值固定时的第二三个值。 解题代码&#xff1a…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA

浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求&#xff0c;本次涉及的主要是收费汇聚交换机的配置&#xff0c;浪潮网络设备在高速项目很少&#xff0c;通…...