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中利用函数装饰器实现备忘功能
Mar 30 Python
Python字符编码判断方法分析
Jul 01 Python
利用Python生成文件md5校验值函数的方法
Jan 10 Python
Python实现向服务器请求压缩数据及解压缩数据的方法示例
Jun 09 Python
python opencv人脸检测提取及保存方法
Aug 03 Python
python list格式数据excel导出方法
Oct 31 Python
django框架基于模板 生成 excel(xls) 文件操作示例
Jun 19 Python
python:动态路由的Flask程序代码
Nov 22 Python
python GUI库图形界面开发之PyQt5开发环境配置与基础使用
Feb 25 Python
浅谈pytorch 模型 .pt, .pth, .pkl的区别及模型保存方式
May 25 Python
python安装后的目录在哪里
Jun 21 Python
Python实现敏感词过滤的4种方法
Sep 12 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的mkdir()函数创建文件夹比较安全的权限设置方法
2014/07/28 PHP
PHP实现的下载远程图片自定义函数分享
2015/01/28 PHP
php设计模式之单例模式用法经典示例分析
2019/09/20 PHP
javascript 读取xml,写入xml 实现代码
2009/07/10 Javascript
学习JavaScript的最佳方法分享
2011/10/21 Javascript
封装好的一个万能检测表单的方法
2015/01/21 Javascript
JS实现在页面随时自定义背景颜色的方法
2015/02/27 Javascript
jquery京东商城双11焦点图多图广告特效代码分享
2015/09/06 Javascript
VueJs组件prop验证简单介绍
2017/09/12 Javascript
vue动态路由配置及路由传参的方式
2018/05/23 Javascript
webpack4之SplitChunksPlugin使用指南
2018/06/12 Javascript
js prototype和__proto__的关系是什么
2019/08/23 Javascript
layui table动态表头 改变表格头部 重新加载表格的方法
2019/09/21 Javascript
从零搭一个自用的前端脚手架的方法步骤
2019/09/23 Javascript
Vue 实现输入框新增搜索历史记录功能
2019/10/15 Javascript
Vue v-for循环之@click点击事件获取元素示例
2019/11/09 Javascript
使用Typescript和ES模块发布Node模块的方法
2020/05/25 Javascript
python多线程扫描端口示例
2014/01/16 Python
在Django的模型中执行原始SQL查询的方法
2015/07/21 Python
Python简单遍历字典及删除元素的方法
2016/09/18 Python
python实现发送邮件功能代码
2017/12/14 Python
Python操作MySQL数据库的三种方法总结
2018/01/30 Python
Python的iOS自动化打包实例代码
2018/11/22 Python
python实现汽车管理系统
2018/11/30 Python
Python元组常见操作示例
2019/02/19 Python
自适应线性神经网络Adaline的python实现详解
2019/09/30 Python
Python用类实现扑克牌发牌的示例代码
2020/06/01 Python
什么是python的自省
2020/06/21 Python
Manjaro、pip、conda更换国内源的方法
2020/11/17 Python
python用700行代码实现http客户端
2021/01/14 Python
八一建军节部队活动方案
2014/02/04 职场文书
西式婚礼主持词
2014/03/13 职场文书
人力资源管理专业自荐书
2014/07/07 职场文书
一文搞懂redux在react中的初步用法
2021/06/09 Javascript
Vue中使用import进行路由懒加载的原理分析
2022/04/01 Vue.js
Win10防火墙白名单怎么设置?Win10添加防火墙白名单方法
2022/04/06 数码科技