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

Python协程(generator, yield, send)

      Python对协程的支持是通过generator生成器实现的。在generator中,不但可以通过for循环来迭代,还可以不断调用next()函数获取由yield语句返回的下一个值。

def foo():
	print("starting...")
	while True:
		res = yield 4
		print("res:",res)

g = foo()
print(next(g))
print("*"*20)
print(next(g))

执行过程

1.程序开始执行以后,因为foo函数中有yield关键字,所以foo函数并不会真的执行,而是先得到一个生成器g(相当于一个对象)

2.直到调用next方法,foo函数正式开始执行,先执行foo函数中的print方法,然后进入while循环

3.程序遇到yield关键字,然后把yield想成return,return了一个4之后,程序停止,并没有执行赋值给res操作,此时next(g)语句执行完成,所以输出的前两行(第一个是while上面的print的结果,第二个是return出的结果)是执行print(next(g))的结果

4.程序执行print(“*”*20),输出20个*

5.又开始执行下面的print(next(g),这个时候和上面那个差不多,不过不同的是,这个时候是从刚才那个next程序停止的地方开始执行的,也就是要执行res的赋值操作,这时候要注意,这个时候赋值操作的右边是没有值的(因为刚才那个是return出去了,并没有给赋值操作的左边传参数),所以这个时候res赋值是None,所以接着下面的输出就是res:None

6.程序会继续在while里执行,又一次碰到yield,这个时候同样return出4,然后程序停止,print函数输出的4就是这次return出的4。

yield简单实现协程

import time

def A():
	while True:
		print('----A----')
		yield
		time.sleep(0.5)

def B(c):
	while  True:
		print('----B----')
		c.__next__()
		time.sleep(0.5)

if __name__ == '__main__':
	a = A()
	B(a)

yield中send函数的使用

      send()发送数据

      send 是发送一个参数给 res 的, 因为上面讲到, return 的时候, 并没有把 4 赋值给 res,下次执行的时候只好继续执行赋值操作, 只好赋值为 None 了, 而如果用 send 的话, 开始执行的时候, 先接着上一次(return 4 之后) 执行, 先把 10 赋值给了 res,然后执行 next 的作用,遇见下一回的 yield, return 出结果后结束

def foo():
	print("starting...")
	while True:
		res = yield 4
		print("res:",res)

g = foo()
print(next(g))
print("*"*20)
print(g.send(10))

协程实现生产者消费者

import time

#生产者
def produce(c):
	c.send(None)
	for i in range(1,6):
		print('生产者生产%d 产品'%i)
		c.send(str(i))
		time.sleep(1)

#消费者
def customer():
	res = ''
	while True:
		data = yield res
		if not data:
			return 
		print('消费者消费%s产品'%data)


if __name__ == '__main__':
	c = customer()
	produce(c)

相关文章:

  • 虚拟机 虚拟硬盘
  • 8086处理器 硬盘
  • 虚拟机快照
  • 虚拟机克隆 将虚拟机导出为 OVF 格式
  • VMware虚拟机与主机共享文件夹
  • Python异步IO协程 (asyncio)
  • 编译原理 1.1
  • 编译原理1.2
  • 汇编语言的种类
  • Bochs虚拟机 编写主引导扇区程序并执行
  • 编译原理2.1
  • Python 函数式编程(一):高阶函数/函数名变量
  • Pycharm debug
  • MyOS(二):用Java和汇编开发一个helloworld操作系统内核
  • 仿QQ聊天室项目
  • “大数据应用场景”之隔壁老王(连载四)
  • HTTP传输编码增加了传输量,只为解决这一个问题 | 实用 HTTP
  • LeetCode18.四数之和 JavaScript
  • VirtualBox 安装过程中出现 Running VMs found 错误的解决过程
  • Vue UI框架库开发介绍
  • 使用API自动生成工具优化前端工作流
  • 用jQuery怎么做到前后端分离
  • ​人工智能书单(数学基础篇)
  • ​直流电和交流电有什么区别为什么这个时候又要变成直流电呢?交流转换到直流(整流器)直流变交流(逆变器)​
  • $().each和$.each的区别
  • $.ajax()参数及用法
  • %check_box% in rails :coditions={:has_many , :through}
  • (九)信息融合方式简介
  • (十八)用JAVA编写MP3解码器——迷你播放器
  • (学习日记)2024.04.10:UCOSIII第三十八节:事件实验
  • (转)Unity3DUnity3D在android下调试
  • (轉貼) 2008 Altera 亞洲創新大賽 台灣學生成果傲視全球 [照片花絮] (SOC) (News)
  • .gitignore
  • .NET Core引入性能分析引导优化
  • .NET Micro Framework初体验
  • .NET 使用 ILMerge 合并多个程序集,避免引入额外的依赖
  • .NET/ASP.NETMVC 深入剖析 Model元数据、HtmlHelper、自定义模板、模板的装饰者模式(二)...
  • .NET4.0并行计算技术基础(1)
  • .net实现头像缩放截取功能 -----转载自accp教程网
  • .NET运行机制
  • .Net转前端开发-启航篇,如何定制博客园主题
  • [ Algorithm ] N次方算法 N Square 动态规划解决
  • [ NOI 2001 ] 食物链
  • [1204 寻找子串位置] 解题报告
  • [2018/11/18] Java数据结构(2) 简单排序 冒泡排序 选择排序 插入排序
  • [C# WPF] 如何给控件添加边框(Border)?
  • [C#]winform部署yolov9的onnx模型
  • [Django 0-1] Core.Handlers 模块
  • [Godot] 3D拾取
  • [Google Guava] 2.1-不可变集合
  • [halcon案例2] 足球场的提取和射影变换
  • [HCTF 2018]WarmUp (代码审计)
  • [I2C]I2C通信协议详解(二) --- I2C时序及规格指引
  • [IE技巧] IE 中打开Office文件的设置
  • [JavaWeb玩耍日记]Maven的安装与使用