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

news2025/1/11 14:25:32

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 = 0
	sum = 0
	def inner(value):
		nonlocal count
		nonlocal sum
		count += 1
		sum += value
		return sum/count
	return inner

def 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 deque

def 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:
            yield

def 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`
        yield

def coordinator():
    dq = deque(maxlen=2)
    # instantiate producer and consumer generator
    producer = produce_element(dq, 5)
    consumer = consume_element(dq)

    while True:
        try:
            # producer fills deque
            print('next producer...')
            next(producer)
        except StopIteration:
            break
        finally:
            # consumer empties deque
            print('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 getgeneratorstate


    def gen(flowers):
        for flower in flowers:
            print(f'Inside loop:{getgeneratorstate(flower_gen)}')
            yield flower


    flower_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_CREATED

getting 1st flower
Inside loop:GEN_RUNNING
--== azalea
After getting first flower: GEN_SUSPENDED

Inside loop:GEN_RUNNING
Inside loop:GEN_RUNNING
Get all flowers: ['Forsythia', 'violas']

After getting all flowers: GEN_CLOSED

Process 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!
下一篇文章介绍如何传值到生成器

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1208268.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

spring-cloud-注册中心

一、服务注册中心组件(*) 定义:服务注册中心就是在整个微服务架构单独抽取一个服务,该服务不做项目中任何业务功能,仅用来在微服务中记录微服务、对微服务进行健康状态检查,及服务元数据信息存储常用的注册中心:eurek…

python实现双臂老虎机k-armed-bandit

老虎机,投入钱币会随机返还钱币(reward) 这里设置两台老虎机,一台均值500,标准差5,一台均值550,标准差10 初始值均为998,更新规则为reward之和/轮数 最后结果会在均值附近收敛 impo…

Eigen的基操

转自博客 博客

解析SQL 获取表、字段及SQL查询参数

解析SQL 获取表、字段及SQL查询参数 1. 执行效果2. 使用2.1 引入依赖2.2 相关实体2.3 工具类 1. 执行效果 2. 使用 2.1 引入依赖 <!-- sql 解析处理--><dependency><groupId>com.github.jsqlparser</groupId><artifactId>jsqlparser</artifa…

2022年12月 Python(五级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 下面哪个语句正确定义了元组类型数据tuple1?( ) A: tuple1=[“张三”,“李四”,“王五”] B: tuple1=(“张三”;“李四”;“王五”) C: tuple1=(张三,李四,王五) D: tuple1=(“张三…

Mybatis-Plus最新教程

目录 原理&#xff1a;MybatisPlus通过扫描实体类&#xff0c;并基于反射获取实体类信息作为数据库信息。 ​编辑1.添加依赖 2.常用注解 3.常见配置&#xff1a; 4.条件构造器 5.QueryWrapper 6.UpdateWrapper 7.LambdaQueryWrapper:避免硬编码 8.自定义SQL 9.Iservic…

C++——友元函数

如下是一个日期类&#xff1a; class Date { public:Date(int year 2023, int month 10, int day 1){_year year;_month month;_day day;if (_month < 1 || month > 12 || _day < 1 || _day > GetMonthDay(_year, _month)){cout << "日期不规范&…

[MySQL] MySQL中的数据类型

在MySQL中&#xff0c;数据类型用于定义表中列的数据的类型。在前面的几篇文章中&#xff0c;我们也会看到有很多的数据类型&#xff0c;例如&#xff1a;char、varchar、date、int等等。本篇文章会对常见的数据类型进行详细讲解。希望会对你有所帮助&#xff01; 文章目录 一、…

[黑马程序员Pandas教程]——Pandas读取保存数据

目录&#xff1a; 学习目标读写文件 写文件读取文件 index_col参数指定索引parse_dates参数指定列解析为时间日期类型encoding参数指定编码格式读取tsv文件Pandas读写文件小结读写数据库 安装pymysql包将数据写入数据库从数据库中加载数据总结项目地址 1.学习目标 能够使用Pan…

吊打Fast Request还免费? 这款插件真心好用!

今天给大家推荐一款IDEA插件&#xff1a;Apipost Helper&#xff0c;比Fast Request更好用并且完全免费&#xff01;三大亮点功能&#xff1a;写完代码IDEA内一键生成API文档&#xff1b;写完代码IDEA内一键调试&#xff0c;&#xff1b;生成API目录树&#xff0c;双击即可快速…

keil5暗色主题配置

在keil文件目录下找到global.prop 将以下内容替换至该文件即可 # properties for all file types indent.automatic1 virtual.space0 view.whitespace0 view.endofline0 code.page0 caretline.visible0 highlight.matchingbraces1 print.syntax.coloring1 use.tab.color1 crea…

PostgreSQL基本操作

目录 1.源码安装PostgreSQL 1.1.前置条件&#xff08;root下操作&#xff09; 1.1.1.卸载yum安装的postgresql 1.1.2.创建postgres用户 1.1.3.安装部分依赖 1.1.4.源码安装uuid 1.2.安装PostgreSQL 1.2.1.使用postgres用户管理PostgreSQL 1.2.2.下载解压postgres12源码…

【算法每日一练]-图论(保姆级教程 篇1(模板篇)) #floyed算法 #dijkstra算法 #spfa算法

今天开始讲图论 目录 图的存储 算任意两点的最短路径: floyed算法&#xff1a; 算一个点到其他所有点的最短距离 dijkstra算法: spfa算法&#xff1a; 图的存储 其实&#xff1a;邻接矩阵和链式向前星都能存边的信息&#xff0c;vector只能存点的信息&#xff0c;再搭配上v[]…

【JUC】四、可重入锁、公平锁、非公平锁、死锁现象

文章目录 1、synchronized2、公平锁和非公平锁3、可重入锁4、死锁 1、synchronized 写个demo&#xff0c;具体演示下对象锁与类锁&#xff0c;以及synchronized同步下的几种情况练习分析。demo里有资源类手机Phone&#xff0c;其有三个方法&#xff0c;发短信和发邮件这两个方…

加速可编程创新,2023年英特尔FPGA中国技术日披露全矩阵FPGA产品与应用方案

在新场景、新应用海量增长的驱动下&#xff0c;中国本地市场对于FPGA产品的需求也在日益多元化和快速扩展。我们始终致力于以中国客户的实际需求为导向&#xff0c;基于领先的FPGA产品和软件为千行百业提供全场景的解决方案。——叶唯琛 英特尔可编程方案事业部中国总经理 今日…

智能运维软件,提升效率的利器

随着信息技术的飞速发展&#xff0c;企业对于IT系统的依赖程度日益加深。为保障IT系统的稳定运行&#xff0c;越来越多的企业选择智能运维管理软件&#xff0c;以全面高效的监控和管理系统和资产情况。 一、运维监控平台的重要性 无监控&#xff0c;不运维。将资产并入监控系…

盘点72个ASP.NET Core源码Net爱好者不容错过

盘点72个ASP.NET Core源码Net爱好者不容错过 学习知识费力气&#xff0c;收集整理更不易。 知识付费甚欢喜&#xff0c;为咱码农谋福利。 链接&#xff1a;https://pan.baidu.com/s/1nlQLLly_TqGrs5O8eOmZjA?pwd8888 提取码&#xff1a;8888 项目名称 (Chinese) 物业收费…

敏捷开发中如何写好用户故事

写好用户故事是敏捷开发中非常重要的一环&#xff0c;它们是描述用户需求的核心。以下是一些关于如何编写优秀用户故事的建议&#xff1a; 使用标准模板&#xff1a; 一个常用的用户故事模板是“As a [用户角色]&#xff0c;I want [功能]&#xff0c;so that [价值]”。这种模…

flutter下拉列表

下拉列表 内容和下拉列表的标题均可滑动 Expanded&#xff1a; 内容限制组件&#xff0c;将其子类中的无限扩展的界面限制在一定范围中。在此使用&#xff0c;是为了防止下拉列表中的内容超过了屏幕限制。 SingleChildScrollView&#xff1a; 这个组件&#xff0c;从名字中可…

JavaScript中的原型和原型链

给大家推荐一个实用面试题库 1、前端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;web前端面试题库 原型和原型链是JavaScript中一个重要且常常被误解的概念。它们在理解对象、继承和属性查找时扮演着关键的角色。 1…