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 26 Python
使用Python编写一个简单的tic-tac-toe游戏的教程
Apr 16 Python
在python3.5中使用OpenCV的实例讲解
Apr 02 Python
Windows上使用Python增加或删除权限的方法
Apr 24 Python
python 定义n个变量方法 (变量声明自动化)
Nov 10 Python
使用python3实现操作串口详解
Jan 01 Python
python数据挖掘需要学的内容
Jun 23 Python
手把手教你进行Python虚拟环境配置教程
Feb 03 Python
python实现扫雷游戏
Mar 03 Python
Python 如何批量更新已安装的库
May 26 Python
关于PyCharm安装后修改路径名称使其可重新打开的问题
Oct 20 Python
Python中文分词库jieba(结巴分词)详细使用介绍
Apr 07 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/21 PHP
php桌面中心(三) 修改数据库
2007/03/11 PHP
php与paypal整合方法
2010/11/28 PHP
phpcms手机内容页面添加上一篇和下一篇
2015/06/05 PHP
Javascript 类与静态类的实现
2010/04/01 Javascript
EasyUI的treegrid组件动态加载数据问题的解决办法
2011/12/11 Javascript
checkbox勾选判断代码分析
2014/06/11 Javascript
Javascript 实现简单计算器实例代码
2016/10/23 Javascript
jquery popupDialog 使用 加载jsp页面的方法
2016/10/25 Javascript
JavaScript注入漏洞的原理及防范(详解)
2016/12/04 Javascript
JavaScript使用原型和原型链实现对象继承的方法详解
2017/04/05 Javascript
详解如何使用babel进行es6文件的编译
2018/05/29 Javascript
vue-router 源码之实现一个简单的 vue-router
2018/07/02 Javascript
Node.js EventEmmitter事件监听器用法实例分析
2019/01/07 Javascript
详解Angular Karma测试的持续集成实践
2019/11/15 Javascript
vue全屏事件开发详解
2020/06/17 Javascript
JavaScript ES 模块的使用
2020/11/12 Javascript
Python中的闭包总结
2014/09/18 Python
以一段代码为实例快速入门Python2.7
2015/03/31 Python
python利用MethodType绑定方法到类示例代码
2017/08/27 Python
Python 3.x读写csv文件中数字的方法示例
2017/08/29 Python
Python并发之多进程的方法实例代码
2018/08/15 Python
pycharm打开命令行或Terminal的方法
2019/01/16 Python
django 连接数据库出现1045错误的解决方式
2020/05/14 Python
好药师网上药店:安全合法的网上药品零售药房
2017/02/15 全球购物
英文留学推荐信范文
2014/01/25 职场文书
《骆驼和羊》教学反思
2014/02/27 职场文书
阳光体育活动实施方案
2014/05/25 职场文书
班训口号大全
2014/06/18 职场文书
物业管理委托协议(2篇)
2014/09/23 职场文书
企业三严三实学习心得体会
2014/10/13 职场文书
2014幼儿园教育教学工作总结
2014/12/17 职场文书
五年级数学教学反思
2016/02/16 职场文书
小学音乐课歌曲《堆雪人》教学反思
2016/02/18 职场文书
如何把新闻人物写得立体、鲜活?
2019/08/14 职场文书
五年级作文之想象作文
2019/10/30 职场文书