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

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

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

相关文章

ESP32网络开发实例-BME280传感器数据保存到InfluxDB时序数据库

BME280传感器数据保存到InfluxDB时序数据库 文章目录 BME280传感器数据保存到InfluxDB时序数据库1、BM280和InfluxDB介绍2、软件准备3、硬件准备4、代码实现在本文中,将详细介绍如何将BME280传感器数据上传到InfluxDB中,方便后期数据处理。 1、BM280和InfluxDB介绍 InfluxDB…

tracert命令

前言:今天在阅读“Web性能权威指南”这本书的时候,发现 tracert 这个命令挺有意思的,在分析网络性能瓶颈的时候也能使用的到,在此就小记一笔以备后用。 1:作用 tracert 是一个简单的网络诊断工具,可以列出…

如何在Windows 10中进行屏幕截图

本文介绍如何在Windows 10中捕获屏幕截图,包括使用键盘组合、使用Snipping Tool、Snipp&Sketch Tool或Windows游戏栏。 使用打印屏幕在Windows 10中捕获屏幕截图 在Windows 10中捕获屏幕截图的最简单方法是按下键盘上的PrtScWindows键盘组合。你将看到屏幕短暂…

python自动化第一篇—— 带图文的execl的自动化合并

简述 最近接到一个需求,需要为公司里的一个部门提供一个文件上传自动化合并的系统,以供用户稽核,谈到自动化,肯定是选择python,毕竟python的轮子多。比较了市面上几个用得多的python库,我最终选择了xlwings…

将按键放到输入框内:

如何将将Button放到输入框内&#xff1f; 效果图&#xff1a; 步骤如下&#xff1a; button 外围用template 包裹一层 <template #suffix v-if"row.WorkerRole TPM"> <el-inputtype"text"v-model"row.JobNumber"placeholder"…

云原生下GIS服务规划与设计

作者&#xff1a;lisong 目录 背景云原生环境下GIS服务的相关概念GIS服务在云原生环境下的规划调度策略GIS服务在云原生环境下的调度手段GIS服务在云原生环境下的服务规划调度实践 背景 作为云原生GIS系统管理人员&#xff0c;在面对新建的云GIS系统时&#xff0c;通常需要应对…

使用 PYTORCH 进行图像风格迁移

一、介绍 本教程介绍如何实现 由 Leon A. Gatys、Alexander S. Ecker 和 Matthias Bethge 开发的神经风格算法。神经风格或神经传输允许您拍摄图像并以新的艺术风格再现它。该算法采用三幅图像&#xff0c;即输入图像、内容图像和风格图像&#xff0c;并将输入更改为类似于内容…

Python框架篇(1):FastApi-快速入门

1.介绍 前言: 不管学什么语言&#xff0c;都应该至少掌握一个框架&#xff0c;方面我们后续&#xff0c;进行服务部署、服务对外支持等; 1.1 官网介绍 下面是来自FastAPI官网的介绍: FastAPI 是一个用于构建 API 的现代、快速&#xff08;高性能&#xff09;的 web 框架&#…

为忙碌的软件工程师精心准备的编码面试准备材料,超过 100,000 人受益!

这是一个针对技术面试准备的手册。它收集了大量的面试问题和答案&#xff0c;涵盖了算法、系统设计、前端等主题&#xff0c;并且还在不断更新和完善中。 这个项目是“Tech Interview Handbook”&#xff0c;解决了求职者在技术面试中遇到的各种难题&#xff0c;帮助他们更好地…

C++ Qt 学习(六):Qt http 编程

1. http 基础 HTTP 基础教程C Web 框架 drogonoatpp 2. C Qt 用户登录、注册功能实现 login_register.h #pragma once#include <QtWidgets/QDialog> #include "ui_login_register.h" #include <QNetworkReply>class login_register : public QDialog…

开源网安受邀参加网络空间安全合作与发展论坛,为软件开发安全建设献计献策

​11月10日&#xff0c;在广西南宁举办的“2023网络空间安全合作与发展论坛”圆满结束。论坛在中国兵工学会的指导下&#xff0c;以“凝聚网络空间安全学术智慧&#xff0c;赋能数字经济时代四链融合”为主题&#xff0c;邀请了多位专家及企业代表共探讨网络安全发展与数字经济…

《网络协议》05. 网络通信安全 · 密码技术

title: 《网络协议》05. 网络通信安全 密码技术 date: 2022-09-10 15:16:15 updated: 2023-11-12 07:03:52 categories: 学习记录&#xff1a;网络协议 excerpt: 网络通信安全&#xff08;ARP 欺骗&#xff0c;DoS & DDoS&#xff0c;SYN 洪水攻击&#xff0c;LAND 攻击&a…

MVC使用的设计模式

MVC使用的设计模式 一、背景 MVC模式是"Model-View-Controller"的缩写&#xff0c;中文翻译为"模式-视图-控制器"。MVC应用程序总是由这三个部分组成。Event(事件)导致Controller改变Model或View&#xff0c;或者同时改变两者。只要Controller改变了Model…

5个用于地理空间数据分析的Python包

大家好&#xff0c;地理空间数据分析在城市规划、环境研究、农业和交通等行业中至关重要。不断增长的需求导致Python包在各种地理数据分析要求上的使用增加&#xff0c;例如分析气候模式、研究城市发展或跟踪疾病传播等&#xff0c;评估和选择具有快速处理、修改和可视化能力的…

IDEA安装配置SceneBuilder

1、下载 SceneBuilder 地址&#xff1a; Scene Builder - Gluon ​​​​​​​ Scene Builder | JavaFX中文官方网站 选择符合自己系统版本&#xff0c;JAVA版本的下载 2、安装SceneBuilder 执行下载的 SceneBuilder 安装程序&#xff0c;并按照安装向导的指示进行…

高防IP可以抵御哪些恶意攻击

高防IP协议可以隐藏用户的站点&#xff0c;使得攻击者无法发现恶意攻击的目标网络资源&#xff0c;从而提高了源站的安全性。能够有效抵御常见的恶意攻击类型ICMPFlood、UDPFlood、 TCPFlood、SYNFlood、ACKFlood等&#xff0c;帮助游戏、金 融、电子商务、互联网、政企等行业抵…

实际使用Elasticdump工具对Elasticsearch集群进行数据备份和数据还原

文/朱季谦 目录一、Elasticdump工具介绍二、Elasticdump工具安装三、Elasticdump工具使用 最近在开发当中做了一些涉及到Elasticsearch映射结构及数据导出导入的工作&#xff0c;怕以后会把这过程忘记&#xff0c;可谓好记性不如烂笔头&#xff0c;故而记录成一篇博文。 玩El…

钉钉统计部门个人请假次数go

前言 最近小组需要统计部门各种请假次数&#xff0c;写了一个方法&#xff0c;第一次实战中用到递归函数&#xff0c;简单记录一下。 效果展示 这些数据不需要返回json&#xff0c;这里这样是为了方便测试。可以通过这些数据完成其它的操作。 功能实现 钉钉服务端调试工具A…

Java主流分布式解决方案多场景设计与实战

Java的主流分布式解决方案的设计和实战涉及到多个场景&#xff0c;包括但不限于以下几点&#xff1a; 分布式缓存&#xff1a;在Java的分布式系统中&#xff0c;缓存是非常重要的一部分。常用的分布式缓存技术包括Redis、EhCache等。这些缓存技术可以用来提高系统的性能和响应…

多个Obj模型合并

MergeObj&#xff08;合并Obj模型&#xff09; 1 概述 由于项目原因&#xff0c;需要下载谷歌地图上的模型&#xff0c;关于谷歌模型下载的&#xff0c;见我的CSDN博客. 由于下载谷歌地图上的数据&#xff0c;会分多个模块下载。下载完成后&#xff0c;怎么合并&#xff0c;在…