详解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 相关文章推荐
简述Python中的面向对象编程的概念
Apr 27 Python
Python基于PycURL实现POST的方法
Jul 25 Python
Python网络爬虫项目:内容提取器的定义
Oct 25 Python
Python中支持向量机SVM的使用方法详解
Dec 26 Python
Python字典操作详细介绍及字典内建方法分享
Jan 04 Python
Python生成任意范围任意精度的随机数方法
Apr 09 Python
Python实现爬取百度贴吧帖子所有楼层图片的爬虫示例
Apr 26 Python
python2.7和NLTK安装详细教程
Sep 19 Python
python简单实现AES加密和解密
Mar 28 Python
python3中编码获取网页的实例方法
Nov 16 Python
python中使用np.delete()的实例方法
Feb 01 Python
Python调用腾讯API实现人脸身份证比对功能
Apr 04 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
ajax实现无刷新分页(php)
2010/07/18 PHP
一道关于php变量引用的面试题
2010/08/08 PHP
php中http与https跨域共享session的解决方法
2014/12/20 PHP
PHP定时执行任务实现方法详解(Timer)
2015/07/30 PHP
Joomla实现组件中弹出一个模式(modal)窗口的方法
2016/05/04 PHP
PDO::_construct讲解
2019/01/27 PHP
IE FF OPERA都可用的弹出层实现代码
2009/09/29 Javascript
javascript &&和||运算法的另类使用技巧
2009/11/28 Javascript
关于js内存泄露的一个好例子
2013/12/09 Javascript
Javascript中的call()方法介绍
2015/03/15 Javascript
jQuery使用post方法提交数据实例
2015/03/25 Javascript
Express实现前端后端通信上传图片之存储数据库(mysql)傻瓜式教程(二)
2015/12/10 Javascript
Reactjs实现通用分页组件的实例代码
2017/01/19 Javascript
去掉vue 中的代码规范检测两种方法(Eslint验证)
2018/03/21 Javascript
angular4自定义组件非input元素实现ngModel双向数据绑定的方法
2018/12/28 Javascript
vue路由导航守卫和请求拦截以及基于node的token认证的方法
2019/04/07 Javascript
vue-cli 3 全局过滤器的实例代码详解
2019/06/03 Javascript
vue3.0中的双向数据绑定方法及优缺点
2019/08/01 Javascript
vue中axios的二次封装实例讲解
2019/10/14 Javascript
Vue两种组件类型:递归组件和动态组件的用法
2020/08/06 Javascript
numpy 计算两个数组重复程度的方法
2018/11/07 Python
Python HTML解析器BeautifulSoup用法实例详解【爬虫解析器】
2019/04/05 Python
python实现两个经纬度点之间的距离和方位角的方法
2019/07/05 Python
Python实现自动访问网页的例子
2020/02/21 Python
150行Python代码实现带界面的数独游戏
2020/04/04 Python
Python+Django+MySQL实现基于Web版的增删改查的示例代码
2020/05/13 Python
谈谈python垃圾回收机制
2020/09/27 Python
如何在Win10系统使用Python3连接Hive
2020/10/15 Python
HTML5 常用语法一览(列举不支持的属性)
2010/01/26 HTML / CSS
美国开幕式潮店:Opening Ceremony
2018/02/10 全球购物
院党委组织查摆问题对照检查材料思想汇报2014
2014/10/08 职场文书
励志语录:时光飞逝,请学会珍惜所有的人和事
2020/01/16 职场文书
Win11怎么进入安全模式?Windows 11进入安全模式的方法
2021/11/21 数码科技
Java练习之潜艇小游戏的实现
2022/03/16 Java/Android
MySQL学习之基础操作总结
2022/03/19 MySQL
Python内置类型集合set和frozenset的使用详解
2022/04/26 Python