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实现在Linux系统下更改当前进程运行用户
Feb 04 Python
pycharm中连接mysql数据库的步骤详解
May 02 Python
Python实现求两个csv文件交集的方法
Sep 06 Python
Python 关于反射和类的特殊成员方法
Sep 14 Python
python3.x实现发送邮件功能
May 22 Python
在NumPy中创建空数组/矩阵的方法
Jun 15 Python
python实现比较类的两个instance(对象)是否相等的方法分析
Jun 26 Python
使用django的objects.filter()方法匹配多个关键字的方法
Jul 18 Python
python @classmethod 的使用场合详解
Aug 23 Python
使用 tf.nn.dynamic_rnn 展开时间维度方式
Jan 21 Python
Python进程Multiprocessing模块原理解析
Feb 28 Python
如何使用Tkinter进行窗口的管理与设置
Jun 30 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
全国FM电台频率大全 - 23 四川省
2020/03/11 无线电
最小化数据传输――在客户端存储数据
2006/10/09 PHP
php页面防重复提交方法总结
2013/11/25 PHP
服务器迁移php版本不同可能诱发的问题
2015/12/22 PHP
PHP闭包函数详解
2016/02/13 PHP
PHP 观察者模式深入理解与应用分析
2019/09/25 PHP
JS JavaScript获取Url参数,src属性参数
2021/03/09 Javascript
javascript动画之圆形运动,环绕鼠标运动作小球
2010/07/20 Javascript
JS 添加网页桌面快捷方式的代码详细整理
2012/12/27 Javascript
js加密解密字符串可自定义密码因子
2014/05/13 Javascript
jQuery控制cookie过期时间的方法
2015/04/07 Javascript
JS模拟并美化的表单控件完整实例
2015/08/19 Javascript
jQuery模仿阿里云购买服务器选择购买时间长度的代码
2016/04/29 Javascript
原生js实现中奖信息无间隙滚动效果
2017/01/18 Javascript
详解Vue 2.0封装axios笔记
2017/06/22 Javascript
vue.js实例todoList项目
2017/07/07 Javascript
Angular使用ControlValueAccessor创建自定义表单控件
2019/03/08 Javascript
jquery 键盘事件 keypress() keydown() keyup()用法总结
2019/10/23 jQuery
element-ui如何防止重复提交的方法步骤
2019/12/09 Javascript
JavaScript实现简单贪吃蛇效果
2020/03/09 Javascript
vue-router重写push方法,解决相同路径跳转报错问题
2020/08/07 Javascript
pycharm 使用心得(四)显示行号
2014/06/05 Python
python字符串替换第一个字符串的方法
2019/06/26 Python
基于python爬取有道翻译过程图解
2020/03/31 Python
Vrbo西班牙:预订您的度假公寓(公寓、乡村房屋…)
2020/04/27 全球购物
linux面试相关问题
2013/04/28 面试题
过滤器的用法
2013/10/08 面试题
师范生自荐信
2013/10/27 职场文书
继承公证书样本
2014/04/04 职场文书
员工工作自我评价
2014/09/26 职场文书
检讨书范文500字
2015/01/28 职场文书
2015年教研工作总结
2015/05/23 职场文书
假如给我三天光明:舟逆水而行,人遇挫而达 
2019/10/29 职场文书
python 模块重载的五种方法
2021/04/24 Python
Python 数据可视化之Matplotlib详解
2021/11/02 Python
Python中Schedule模块使用详解 周期任务神器
2022/04/19 Python