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清除字符串里非数字字符的方法
Jul 02 Python
Redis使用watch完成秒杀抢购功能的代码
May 07 Python
python 内置模块详解
Jan 01 Python
python交互界面的退出方法
Feb 16 Python
Python Matplotlib实现三维数据的散点图绘制
Mar 19 Python
python调用动态链接库的基本过程详解
Jun 19 Python
在django中实现页面倒数几秒后自动跳转的例子
Aug 16 Python
Python requests模块cookie实例解析
Apr 14 Python
如何解决pycharm调试报错的问题
Aug 06 Python
pycharm 实现调试窗口恢复
Feb 05 Python
pytorch 实现L2和L1正则化regularization的操作
Mar 03 Python
手把手教你实现PyTorch的MNIST数据集
Jun 28 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基础知识:函数基础知识
2006/12/13 PHP
php生成随机颜色的方法
2014/11/13 PHP
php简单操作mysql数据库的类
2015/04/16 PHP
php递归函数怎么用才有效
2018/02/24 PHP
PHP常用工具函数小结【移除XSS攻击、UTF8与GBK编码转换等】
2019/04/27 PHP
js跳转页面方法实现汇总
2014/02/11 Javascript
更快的异步执行(setTimeout多浏览器)
2014/08/12 Javascript
require.js深入了解 require.js特性介绍
2014/09/04 Javascript
JavaScript中number转换成string介绍
2014/12/31 Javascript
Vue.js实现一个todo-list的上移下移删除功能
2017/06/26 Javascript
利用JS如何计算字符串所占字节数示例代码
2017/09/13 Javascript
vue cli webpack中使用sass的方法
2018/02/24 Javascript
vue2.0结合Element-ui实战案例
2019/03/06 Javascript
java和js实现的洗牌小程序
2019/09/30 Javascript
浅谈鸿蒙 JavaScript GUI 技术栈
2020/09/17 Javascript
[16:56]heroes英雄教学 司夜刺客
2014/09/18 DOTA
[07:49]2014DOTA2国际邀请赛 Newbee夺冠后采访xiao8坦言奖金会上交
2014/07/23 DOTA
[02:50]【扭转乾坤,只此一招】DOTA2永雾林渊版本开启新篇章
2020/12/22 DOTA
PYTHON正则表达式 re模块使用说明
2011/05/19 Python
Python编程实现生成特定范围内不重复多个随机数的2种方法
2017/04/14 Python
python获取网页中所有图片并筛选指定分辨率的方法
2018/03/31 Python
pycharm执行python时,填写参数的方法
2018/10/29 Python
python实现字符串加密 生成唯一固定长度字符串
2019/03/22 Python
Python向excel中写入数据的方法
2019/05/05 Python
pytorch下的unsqueeze和squeeze的用法说明
2021/02/06 Python
使用spring mvc+localResizeIMG实现HTML5端图片压缩上传的功能
2016/12/16 HTML / CSS
ProBikeKit澳大利亚:自行车套件,跑步和铁人三项装备
2016/11/30 全球购物
Kusmi茶美国官网:优质散叶茶和茶包
2019/10/13 全球购物
高中生毕业自我鉴定范文
2013/12/22 职场文书
机械设计制造及其自动化专业求职信
2014/06/17 职场文书
酒店财务部岗位职责
2015/04/14 职场文书
预备党员党支部意见
2015/06/02 职场文书
小兵张嘎电影观后感
2015/06/03 职场文书
网吧温馨提示
2015/07/17 职场文书
初一军训感言
2015/08/01 职场文书
Python实现生成bmp图像的方法
2021/06/13 Python