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 04 Python
python批量修改文件编码格式的方法
May 31 Python
对python:循环定义多个变量的实例详解
Jan 20 Python
Python实现深度遍历和广度遍历的方法
Jan 22 Python
基于pycharm实现批量修改变量名
Jun 02 Python
记录模型训练时loss值的变化情况
Jun 16 Python
Python计算矩阵的和积的实例详解
Sep 10 Python
python PIL模块的基本使用
Sep 29 Python
pytorch简介
Nov 11 Python
Python基础详解之描述符
Apr 28 Python
Python进程池与进程锁之语法学习
Apr 11 Python
python manim实现排序算法动画示例
Aug 14 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反射类ReflectionClass和ReflectionObject的使用方法
2013/11/13 PHP
php中的观察者模式简单实例
2015/01/20 PHP
PHP微信刮刮卡 附微信接口
2016/07/22 PHP
yii2使用gridView实现下拉列表筛选数据
2017/04/10 PHP
jQuery 学习入门篇附实例代码
2010/03/16 Javascript
jquery+ashx无刷新GridView数据显示插件(实现分页、排序、过滤功能)
2010/04/25 Javascript
屏蔽网页右键复制和ctrl+c复制的js代码
2013/01/04 Javascript
关于jquery的多个选择器的使用示例
2013/10/18 Javascript
javascript数组排序汇总
2015/07/07 Javascript
基于Bootstrap漂亮简洁的CSS3价格表(附源码下载)
2017/02/28 Javascript
浅析bootstrap原理及优缺点
2017/03/19 Javascript
JavaScript闭包的简单应用
2017/09/01 Javascript
react-native DatePicker日期选择组件的实现代码
2017/09/12 Javascript
详解微信小程序缓存--缓存时效性
2019/05/02 Javascript
微信小程序事件 bindtap bindinput代码实例
2019/08/26 Javascript
原生javascript制作贪吃蛇小游戏的方法分析
2020/02/26 Javascript
js代码实现轮播图
2020/05/04 Javascript
浅谈Vue 函数式组件的使用技巧
2020/06/16 Javascript
[42:22]DOTA2上海特级锦标赛C组小组赛#1 OG VS Archon第一局
2016/02/27 DOTA
Python实现TCP协议下的端口映射功能的脚本程序示例
2016/06/14 Python
Python3并发写文件与Python对比
2019/11/20 Python
Python使用re模块验证危险字符
2020/05/21 Python
Python 基于jwt实现认证机制流程解析
2020/06/22 Python
python mongo 向数据中的数组类型新增数据操作
2020/12/05 Python
python爬虫scrapy框架之增量式爬虫的示例代码
2021/02/26 Python
css3.0新属性效果在ie下的解决方案
2010/05/10 HTML / CSS
乌克兰时尚鞋子和衣服购物网站:Born2be
2018/05/24 全球购物
巴西Mr. Cat在线商店:购买包包和鞋子
2019/09/08 全球购物
数控专业应届生求职信
2013/11/27 职场文书
2014四风问题对照检查材料范文
2014/09/15 职场文书
党员民主生活会对照检查材料思想汇报
2014/09/28 职场文书
单位租房协议书范本
2014/12/04 职场文书
假如给我三天光明读书笔记
2015/06/26 职场文书
《一面五星红旗》教学反思
2016/02/23 职场文书
python实现MD5进行文件去重的示例代码
2021/07/09 Python
详细介绍MySQL中limit和offset的用法
2022/05/06 MySQL