详解Python生成器和基于生成器的协程


Posted in Python onJune 03, 2021

一、什么是生成器

Generator

1.生成器就是可以生成值的函数
2.当一个函数里有了 yield关键字就成了生成器
3.生成器可以挂起执行并且保持当前执行的状态

代码示例:

def simple_gen():
	yield 'hello'
	yield 'world'

gen = simple_gen()
print(type(gen))  # 'generator' object
print(next(gen))  # 'hello'
print(next(gen))  # 'world'

二、基于生成器的协程

Python3之前没有原生协程,只有基于生成器的协程

1.pep 342(Coroutines via Enhanced Generators)增强生成器功能
2.生成器可能通过 yield 暂停执行和产出数据
3.同时支持send()向生成器发送数据和throw()向生成器抛出异常

Generator Based Corouteine代码示例:

def coro():
	hello = yield 'hello'  # yield 关键字在 = 右边作为表达式,可以被 send 值
	yield hello

c = coro()
# 输出 'hello', 这里调用 next 产出第一个值 'hello',之后函数暂停
print(next(c))
# 再次调用  send 发送值,此时 hello 变量赋值为 'world',然后 yield 产出 hello 变量的值 'world'
print(c.send('world'))
# 之后协程结束,后续再 send 值会抛出异常 StopIteration

运行结果:

详解Python生成器和基于生成器的协程

三、协程的注意点

协程注意点

1.协程需要使用send(None)或者next(coroutine)来预激(prime)才能启动
2.在yield处协程会暂停执行
3.单独的yield value会产出值给调用方
4.可以通过 coroutine.send(value)来给协程发送值,发送的值会赋值给 yield表达式左边的变量value = yield
5.协程执行完成后(没有遇到下一个yield语句)会抛出StopIteration异常

四、协程装饰器

避免每次都要用 send 预激它

from functools import wraps

def coroutine(func):  # 这样就不用每次都用 send(None) 启动了
	“”“装饰器:向前执行到一个 `yield` 表达式,预激 `func` ”“”
	@wrops(func)
	def primer(*args, **kwargs):   # 1
		gen = func(*args, **kwargs)  # 2
		next(gen)  # 3
		return gen  # 4
	return primer

五、python3原生协程

python3.5引入 async/await支持原生协程(native coroutine)

import asyncio
import datetime
import random

async def display_date(num, loop):
	end_time = loop.time() + 50.0
	while True:
		print('Loop: {} Time: {}'.format(num, datetime.datetime.now())
		if (loop.time() + 1.0) >= end_time:
			break
		await asyncio.sleep(random.randint(0, 5))

loop = asyncio.get_event_loop()
asyncio.ensure_future(display_date(1, loop))
asyncio.ensure_future(display_date(2, loop))
loop.run_forever()

 

到此这篇关于详解Python生成器和基于生成器的协程的文章就介绍到这了,更多相关Python生成器与协程内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
wxpython 学习笔记 第一天
Mar 16 Python
推荐11个实用Python库
Jan 23 Python
python数组复制拷贝的实现方法
Jun 09 Python
浅析Python中else语句块的使用技巧
Jun 16 Python
Django实现表单验证
Sep 08 Python
python实现自动登录后台管理系统
Oct 18 Python
Python实现微信消息防撤回功能的实例代码
Apr 29 Python
python面试题Python2.x和Python3.x的区别
May 28 Python
python读写Excel表格的实例代码(简单实用)
Dec 19 Python
python logging 重复写日志问题解决办法详解
Aug 04 Python
python实现邮件循环自动发件功能
Sep 11 Python
Python实现自动整理文件的脚本
Dec 17 Python
实例讲解Python中sys.argv[]的用法
Jun 03 #Python
Django与数据库交互的实现
Jun 03 #Python
Python代码风格与编程习惯重要吗?
Jun 03 #Python
python 经纬度求两点距离、三点面积操作
Jun 03 #Python
如何使用PyCharm及常用配置详解
python for循环赋值问题
Jun 03 #Python
python批量创建变量并赋值操作
Jun 03 #Python
You might like
星际争霸中的对战模式介绍
2020/03/04 星际争霸
洪恩在线成语词典小偷程序php版
2012/04/20 PHP
递归删除一个节点以及该节点下的所有节点示例
2014/03/19 PHP
PHP的Yii框架中过滤器相关的使用总结
2016/03/29 PHP
Laravel使用支付宝进行支付的示例代码
2017/08/16 PHP
50款非常棒的 jQuery 插件分享
2012/03/29 Javascript
讨论html与javascript在浏览器中的加载顺序问题
2013/11/27 Javascript
js中indexof的用法详细解析
2013/12/24 Javascript
javascript计算用户打开网页的停留时间
2014/01/09 Javascript
jquery预览图片实现鼠标放上去显示实际大小
2014/01/16 Javascript
Node.js 学习笔记之简介、安装及配置
2015/03/03 Javascript
jQuery插件datalist实现很好看的input下拉列表
2015/07/14 Javascript
jquery checkbox无法用attr()二次勾选问题的解决方法
2016/07/22 Javascript
webpack构建vue项目的详细教程(配置篇)
2017/07/17 Javascript
JS实现点击循环切换显示内容的方法
2017/10/19 Javascript
JS简单实现动态添加HTML标记的方法示例
2018/04/08 Javascript
LayUI表格批量删除方法
2018/08/15 Javascript
JS中创建自定义类型的常用模式总结【工厂模式,构造函数模式,原型模式,动态原型模式等】
2019/01/19 Javascript
React Ant Design树形表格的复杂增删改操作
2020/11/02 Javascript
pip安装python库的方法总结
2019/08/02 Python
python 解决cv2绘制中文乱码问题
2019/12/23 Python
Django-xadmin后台导入json数据及后台显示信息图标和主题更改方式
2020/03/11 Python
10个python3常用排序算法详细说明与实例(快速排序,冒泡排序,桶排序,基数排序,堆排序,希尔排序,归并排序,计数排序)
2020/03/17 Python
如何理解python面向对象编程
2020/06/01 Python
django haystack实现全文检索的示例代码
2020/06/24 Python
Joseph官网:英国小众奢侈品牌
2019/05/17 全球购物
统计每一学生的平均成绩
2014/06/06 面试题
2019年c语言经典面试题目
2016/08/17 面试题
应届护士求职信范文
2014/01/26 职场文书
竞选生活委员演讲稿
2014/04/28 职场文书
超市客服工作职责
2014/06/11 职场文书
真诚的求职信
2014/07/04 职场文书
党员转正意见怎么写
2015/06/03 职场文书
2019奶茶店创业计划书范本!
2019/07/15 职场文书
python实现股票历史数据可视化分析案例
2021/06/10 Python
戴尔Win11系统no bootable devices found解决教程
2022/09/23 数码科技