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实现身份证号码解析
Sep 01 Python
一些常用的Python爬虫技巧汇总
Sep 28 Python
Python编程argparse入门浅析
Feb 07 Python
python中ASCII码字符与int之间的转换方法
Jul 09 Python
python+opencv实现阈值分割
Dec 26 Python
Python中Numpy ndarray的使用详解
May 24 Python
python切片的步进、添加、连接简单操作示例
Jul 11 Python
浅谈Pytorch中的torch.gather函数的含义
Aug 18 Python
Python 中的 import 机制之实现远程导入模块
Oct 29 Python
Python partial函数原理及用法解析
Dec 11 Python
基于Python数据结构之递归与回溯搜索
Feb 26 Python
Keras Convolution1D与Convolution2D区别说明
May 22 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小偷的核心程序
2007/04/09 PHP
PHP 利用AJAX获取网页并输出的实现代码(Zjmainstay)
2012/08/31 PHP
3款值得推荐的微信开发开源框架
2014/10/28 PHP
PHP.ini安全配置检测工具pcc简单介绍
2015/07/02 PHP
ExtJS 2.0实用简明教程 之Border区域布局
2009/04/29 Javascript
离开页面时检测表单元素是否被修改,提示保存的js代码
2010/08/25 Javascript
深入分析js中的constructor和prototype
2012/04/07 Javascript
JavaScript 数组详解
2013/10/10 Javascript
js日期相关函数总结分享
2013/10/15 Javascript
jquery.validate的使用说明介绍
2013/11/12 Javascript
js判读浏览器是否支持html5的canvas的代码
2013/11/18 Javascript
浅谈JavaScript中数组的增删改查
2016/06/20 Javascript
AngularJs Understanding the Model Component
2016/09/02 Javascript
Node.js操作redis实现添加查询功能
2017/05/25 Javascript
JavaScript实现选中文字提示新浪微博分享效果
2017/06/15 Javascript
vue左右侧联动滚动的实现代码
2018/06/06 Javascript
vue实现引入本地json的方法分析
2018/07/12 Javascript
JS实现的简单分页功能示例
2018/08/23 Javascript
npm ci命令的基本使用方法
2020/09/20 Javascript
[00:09]DOTA2全国高校联赛 精彩活动引爆全场
2018/05/30 DOTA
简单介绍Python中的floor()方法
2015/05/15 Python
python 利用for循环 保存多个图像或者文件的实例
2018/11/09 Python
Django框架静态文件使用/中间件/禁用ip功能实例详解
2019/07/22 Python
Pandas数据离散化原理及实例解析
2019/11/16 Python
python为QT程序添加图标的方法详解
2020/03/09 Python
python百行代码自制电脑端网速悬浮窗的实现
2020/05/12 Python
Python中的流程控制详解
2021/02/18 Python
Superdry极度乾燥官网:日本街头风格,纯英国制造品牌
2016/10/31 全球购物
耐克波兰官方网站:Nike波兰
2019/09/03 全球购物
授权委托书怎么写
2014/04/03 职场文书
食堂标语大全
2014/06/11 职场文书
婚礼女方父母答谢词
2015/01/04 职场文书
工程进度款催款函
2015/06/24 职场文书
网络安全倡议书(3篇)
2019/09/18 职场文书
详解PHP用mb_string处理windows中文字符
2021/05/26 PHP
深入浅出讲解Java8函数式编程
2022/01/18 Java/Android