Python 中由 yield 实现异步操作


Posted in Python onMay 04, 2020

yield在python中初学时,觉得比较难理解。yield的作用:

①返回一个值、②接收调用者的参数

分析下面的代码:

#!/usr/bin/env python3
# -*- coding:utf-8 -*-

def consumer():
  r = ''
  while True:
    n = yield r
    print("[Consumer] n = %d" %n)
    if not n:
      return
    print("[Consumer] consuming %s..." %n)
    r = '200 OK'

def produce(c):
  c.send(None)
  h = 0
  while h < 5:
    h = h + 1
    print("[Producer] producing %d..." %h)
    s = c.send(h)
    print("[Producer] consumer return: %s" %s)
  c.close()

c = consumer() #创建一个生成器
produce(c) #在该函数中,调用生成器的send()方法

Python 中由 yield 实现异步操作

结合程序运行过程,可分析出:

第一步:

在produce(c)函数中,调用了c.send(None)启动了生成器,遇到yield暂停;接着执行produce()中接下来的代码,从运行结果看,确实打印出了[Produce] producing 1 … 当程序运行至c.send(h)时,调用生成器并且通过yield传递了参数(h = 1)进入consumer()函数执行。

第二步:

yield传递参数(h=1)给consumer()函数中的n,并接着上一次暂停处往下继续执行,打印出[Consumer] n = 1,[Consumer] consuming 1… ;在consumer()函数中此时 r 被赋值为'200 OK',接着循环遇到yield, consumer()函数又暂停并且返回变量 r 的值,此时程序又进入produce(c)函数中接着执行。

第三步:

produce(c)函数接着第一步中c.send(h)处,继续往下执行打印出[Producer] consumer return: 200 OK,并进行循环,打印[Producer] producing 2… 后,又调用c.send(h) 。。。如此循环回到第一步!

补充知识:python asyncio模型 事件循环

异步建立在事件循环上.

简单来说事件循环:

1.把要执行的函数放入队列

2.取出函数,执行

3.看看还要不要继续放入此函数

4.继续第一步

一个简单的例子说明:

"""
  1.yield 挂起当前函数.
  2.使用调度器循环
  3.使用next唤醒此函数继续执行
"""
def f1():
  for i in range(3):
    print('f1 %d'%i)
    yield
def f2():
  for i in range(5):
    print('f2 %d' %i)
    yield
def f3():
  for i in range(10):
    print('f3 %d'%i)
    yield
#模拟一个调度器
task_q = collections.deque((f1(),f2(),f3()))
#让调度器调度这些生成器们
while task_q:
  task = task_q.popleft() #弹出首个生成器
  try:
    next(task)     #执行,如果没有异常证明此生成器还没执行完成,可以继续放入队列中
    task_q.append(task) #执行完成后,把任务继续添加到队列中.
    time.sleep(0.5)
  except StopIteration as ex:
    pass

以上这篇Python 中由 yield 实现异步操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
如何在Python中编写并发程序
Feb 27 Python
python实现kMeans算法
Dec 21 Python
python matplotlib 注释文本箭头简单代码示例
Jan 08 Python
python3实现基于用户的协同过滤
May 31 Python
对TensorFlow中的variables_to_restore函数详解
Jul 30 Python
利用PyCharm Profile分析异步爬虫效率详解
May 08 Python
简单了解为什么python函数后有多个括号
Dec 19 Python
细数nn.BCELoss与nn.CrossEntropyLoss的区别
Feb 29 Python
浅谈Python 参数与变量
Jun 20 Python
Django中F函数的使用示例代码详解
Jul 06 Python
python 制作网站筛选工具(附源码)
Jan 21 Python
Python用requests库爬取返回为空的解决办法
Feb 21 Python
python 双循环遍历list 变量判断代码
May 04 #Python
Python求解排列中的逆序数个数实例
May 03 #Python
Python3实现个位数字和十位数字对调, 其乘积不变
May 03 #Python
python输入一个水仙花数(三位数) 输出百位十位个位实例
May 03 #Python
Python中实现输入一个整数的案例
May 03 #Python
python中使用input()函数获取用户输入值方式
May 03 #Python
Python run()函数和start()函数的比较和差别介绍
May 03 #Python
You might like
php 将bmp图片转为jpg等其他任意格式的图片
2009/06/29 PHP
浅析php中三个等号(===)和两个等号(==)的区别
2013/08/06 PHP
PHP开发框架kohana3 自定义路由设置示例
2014/07/14 PHP
PHP实现的自定义图像居中裁剪函数示例【测试可用】
2017/08/11 PHP
PHP Include文件实例讲解
2019/02/15 PHP
JQuery 绑定事件时传递参数的实现方法
2009/10/13 Javascript
JQuery 构建客户/服务分离的链接模型中Table中的排序分析
2010/01/22 Javascript
XMLHTTPRequest的属性和方法简介
2010/11/23 Javascript
javascript实现倒计时N秒后网页自动跳转代码
2014/12/11 Javascript
同一个网页中实现多个JavaScript特效的方法
2015/02/02 Javascript
javascript伸缩菜单栏实现代码分享
2015/11/12 Javascript
JS实现随页面滚动显示/隐藏窗口固定位置元素
2016/02/26 Javascript
Bootstrap页面布局基础知识全面解析
2016/06/13 Javascript
checkbox:click事件触发span元素内容改变的方法
2017/09/11 Javascript
JS实现的3des+base64加密解密算法完整示例
2018/05/18 Javascript
前端面试知识点目录一览
2019/04/15 Javascript
vue 兄弟组件的信息传递的方法实例详解
2019/08/30 Javascript
Vue中component标签解决项目组件化操作
2020/09/04 Javascript
[02:28]PWL开团时刻DAY3——Ink Ice与DeMonsTer之间的勾心斗角
2020/11/03 DOTA
Python3爬虫学习入门教程
2018/12/11 Python
python爬虫之验证码篇3-滑动验证码识别技术
2019/04/11 Python
python opencv鼠标事件实现画框圈定目标获取坐标信息
2020/04/18 Python
pycharm快捷键汇总
2020/02/14 Python
Python中的Cookie模块如何使用
2020/06/04 Python
python解释器安装教程的方法步骤
2020/07/02 Python
美国最大的烧烤架和户外生活用品专业零售商:Barbeques Galore
2021/01/09 全球购物
四川成都导游欢迎词
2014/01/18 职场文书
实习报告评语
2014/04/26 职场文书
初中班级口号
2014/06/09 职场文书
开展创先争优活动总结
2014/08/28 职场文书
2014学习优秀共产党员先进事迹思想汇报
2014/09/14 职场文书
医院护士工作检讨书
2014/10/26 职场文书
群众路线剖析材料(四风)
2014/11/05 职场文书
公司经营目标责任书
2015/01/29 职场文书
汽车4S店销售经理岗位职责
2015/04/02 职场文书
Python Django ORM连表正反操作技巧
2021/06/13 Python