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中文件遍历的两种方法
Jun 16 Python
python自动格式化json文件的方法
Mar 11 Python
Python使用cx_Freeze库生成msi格式安装文件的方法
Jul 10 Python
Django跨域请求CSRF的方法示例
Nov 11 Python
Python 数据可视化pyecharts的使用详解
Jun 26 Python
python:按行读入,排序然后输出的方法
Jul 20 Python
python中matplotlib条件背景颜色的实现
Sep 02 Python
解决Python使用列表副本的问题
Dec 19 Python
python如何写try语句
Jul 14 Python
Python中的With语句的使用及原理
Jul 29 Python
python 模拟登录B站的示例代码
Dec 15 Python
Python调用系统命令os.system()和os.popen()的实现
Dec 31 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简单读取xml文件的方法示例
2017/04/20 PHP
PHP实现求连续子数组最大和问题2种解决方法
2017/12/26 PHP
JS中字符问题(二进制/十进制/十六进制及ASCII码之间的转换)
2008/11/03 Javascript
JavaScript初学者应注意的七个细节小结
2012/01/30 Javascript
基于jquery ajax 用户无刷新登录方法详解
2012/04/28 Javascript
学习从实践开始之jQuery插件开发 菜单插件开发
2012/05/03 Javascript
js动态修改整个页面样式达到换肤效果
2014/05/23 Javascript
jQuery实现右侧显示可向左滑动展示的深色QQ客服效果代码
2015/10/23 Javascript
js计算系统当前日期是星期几的方法
2016/07/14 Javascript
关于Vue单页面骨架屏实践记录
2017/12/13 Javascript
webpack多页面开发实践
2017/12/18 Javascript
vue.js分页中单击页码更换页面内容的方法(配合spring springmvc)
2018/02/10 Javascript
jQuery+vue.js实现的多选下拉列表功能示例
2019/01/15 jQuery
JavaScript如何判断input数据类型
2020/02/06 Javascript
Python常见文件操作的函数示例代码
2011/11/15 Python
Pycharm学习教程(3) 代码运行调试
2017/05/03 Python
Python自动化运维_文件内容差异对比分析
2017/12/13 Python
VSCode下好用的Python插件及配置
2018/04/06 Python
Django安装配置mysql的方法步骤
2018/10/15 Python
django 使用 PIL 压缩图片的例子
2019/08/16 Python
Python通过Manager方式实现多个无关联进程共享数据的实现
2019/11/07 Python
基于python cut和qcut的用法及区别详解
2019/11/22 Python
TensorFlow 读取CSV数据的实例
2020/02/05 Python
纯HTML5+CSS3制作生日蛋糕代码
2016/11/16 HTML / CSS
HTML5 Web存储方式的localStorage和sessionStorage进行数据本地存储案例应用
2012/12/09 HTML / CSS
戴森英国官网:Dyson英国
2019/05/07 全球购物
化工专业个人的求职信范文
2013/11/28 职场文书
茶叶店创业计划书范文
2014/01/19 职场文书
大学辅导员事迹材料
2014/02/05 职场文书
《三个小伙伴》教学反思
2014/04/11 职场文书
大专应届毕业生求职信
2014/07/15 职场文书
最美家庭活动方案
2014/08/31 职场文书
2014年体育工作总结
2014/11/24 职场文书
元旦主持词开场白
2015/05/29 职场文书
宝宝满月祝酒词
2015/08/10 职场文书
详解nginx进程锁的实现
2021/06/14 Servers