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实现抓取百度搜索结果页的网站标题信息
Jan 22 Python
python实现超简单端口转发的方法
Mar 13 Python
解决python3 urllib中urlopen报错的问题
Mar 25 Python
python模块smtplib学习
May 22 Python
Python实现的建造者模式示例
Aug 06 Python
python获取微信企业号打卡数据并生成windows计划任务
Apr 30 Python
详解python列表(list)的使用技巧及高级操作
Aug 15 Python
aws 通过boto3 python脚本打pach的实现方法
May 10 Python
python Django 反向访问器的外键冲突解决
May 20 Python
Python获取excel内容及相关操作代码实例
Aug 10 Python
python 制作磁力搜索工具
Mar 04 Python
Python测试框架pytest高阶用法全面详解
Jun 01 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
多数据表共用一个页的新闻发布
2006/10/09 PHP
同一空间绑定多个域名而实现访问不同页面的PHP代码
2006/12/06 PHP
php实现处理输入转义字符的代码
2015/11/08 PHP
深入剖析PHP中printf()函数格式化使用
2016/05/23 PHP
PHP实现网站访问量计数器
2017/10/27 PHP
PHP字符串中抽取子串操作实例分析
2019/06/22 PHP
laravel-admin 中列表筛选方法
2019/10/03 PHP
获取DOM对象的几种扩展及简写
2006/10/09 Javascript
javascript Keycode对照表
2009/10/24 Javascript
jQuery Clone Bug解决代码
2010/12/22 Javascript
用js小类库获取浏览器的高度和宽度信息
2012/01/15 Javascript
精心挑选的12款优秀的基于jQuery的手风琴效果插件和教程
2012/08/22 Javascript
js输出阴历、阳历、年份、月份、周示例代码
2014/01/29 Javascript
Jquery修改页面标题title其它JS失效的解决方法
2014/10/31 Javascript
Backbone.js 0.9.2 源码注释中文翻译版
2015/06/25 Javascript
angularJS与bootstrap结合实现动态加载弹出提示内容
2015/10/16 Javascript
JavaScript如何实现跨域请求
2016/08/05 Javascript
JavaScript使用简单正则表达式的数据验证功能示例
2017/01/13 Javascript
three.js实现圆柱体
2018/12/30 Javascript
JavaScript实现字符串与HTML格式相互转换
2020/03/17 Javascript
vue实现简单全选和反选功能
2020/09/15 Javascript
微信小程序实现选项卡滑动切换
2020/10/22 Javascript
浅谈python中scipy.misc.logsumexp函数的运用场景
2016/06/23 Python
python实现分页效果
2017/10/25 Python
磁盘垃圾文件清理器python代码实现
2020/08/24 Python
解决python os.mkdir创建目录失败的问题
2018/10/16 Python
Python设计模式之简单工厂模式实例详解
2019/01/22 Python
python TK库简单应用(实时显示子进程输出)
2019/10/29 Python
python绘制随机网络图形示例
2019/11/21 Python
pytorch中nn.Conv1d的用法详解
2019/12/31 Python
基于Keras中Conv1D和Conv2D的区别说明
2020/06/19 Python
ghd法国官方网站:英国最受欢迎的美发工具品牌
2019/04/18 全球购物
中专毕业生的自我鉴定
2013/12/01 职场文书
目标管理责任书
2014/04/15 职场文书
软件售后服务承诺书
2014/05/21 职场文书
2015年评职称工作总结范文
2015/04/20 职场文书