博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一个有趣的小例子,带你入门协程模块-asyncio
阅读量:6303 次
发布时间:2019-06-22

本文共 2877 字,大约阅读时间需要 9 分钟。

上篇文章写了关于yield from的用法,简单的了解异步模式,【上次的内容链接】这次让我们通过一个有趣例子带大家了解asyncio基本使用。

目标效果图

在控制台中显示一个由ASCII字符"|/-\"构成的动画旋转指针.

基本原理

1.通过不停的依次顺序迭代"|/-\"中的一个字符。

2.每次输出前使用退格符模拟一个动态效果。所谓的退格符就是删除上一个字符串,并在原来的位置输出新的字符串。
代码实现:

1 import  itertools  2 import sys  3 import time  4 flush=sys.stdout.flush  5 for i in  itertools.cycle("|/-\\"):  6      print('\b'*len(i)+i,end='')  7      flush()  8      time.sleep(.1)复制代码

代码解释

1,2,3行导入需要的包。

4行定义7行调用,强制刷新缓存。

当我们打印一些字符时,并不是调用print函数后就立即打印的。
一般会先将字符送到缓冲区,然后再打印。这就存在一个问题,
如果你想等时间间隔的打印一些字符,
但由于缓冲区没满,不会打印。就需要采取强制刷新等手段了。

5行,使用itertools.cycle无穷的迭代括号内的字符串。

6行,print默认是print(end='\n'),这里修改其默认方法end='',不换行。

关键作用的是'\b','\b'*len(i)表示多次退格,长度由迭代的字符的个数决定。

8行 模拟休眠0.1秒。

这里只是一个简单的效果演示,下面我们使用一个使用协程的例子。

使用asyncio完成同样的功能

该例子参考流畅的python,我对其作了部分修改。先看代码,后面再做解释。

# -*- coding: utf-8 -*-# @Time : 2018/12/19 9:08 PM# @Author : cxa# @File : 18-2.py# @Software: PyCharm# 通过协程以动画形式显示文本式旋转指针import asyncioimport itertoolsimport sysimport timeasync def spin(msg):  # (1)    write, flush = sys.stdout.write, sys.stdout.flush  # (2)    for char in itertools.cycle('|/-\\'):  #(3)         status = char + ' ' + msg        print(status, end='')        flush()  #(4)         # write('\b' * len(status))  # (5)         print('\b' * len(status), end='')  # (6)         try:            await asyncio.sleep(.1)  # (7)         except asyncio.CancelledError: # (8)             break    # write(" " * len(status) + '\b' * len(status))  # (9)     print(" " * len(status) + '\b' * len(status), end='') # (10)async def slow_function():    # 假装等待io一段时间    await asyncio.sleep(3)    return "very good!"async def supervisor():    # loop = asyncio.get_event_loop() # (11)    # spinner = loop.create_task(spin('thking!')) # (12)    spinner = asyncio.ensure_future(spin('thking!'))  # (13)    print('spinner object:', spinner) # (14)    result = await slow_function()  # (15)    spinner.cancel()   # (16)    return resultdef main():    loop = asyncio.get_event_loop()  # (17)    result = loop.run_until_complete(supervisor())  # (18)    loop.close()# (19)    print("Result:", result)if __name__ == '__main__':    main()复制代码

下面对上面编号进行一一讲解。

首先导入必须的包,其中asyncio就是我们要使用的协程包。
(1)def代表一个函数或者方法,如果在前面加async def这个就变成协程了。不再是一个方法。
在python3.4的时候通过使用@asyncio.coroutine来修饰一个函数使其变为一个协程。现在不推荐使用。

(2) 定义对象方便后面使用。

(3)itertools.cycle会把一个可迭代对象无限重复下去。

(4)强制刷新缓存

(5)(6)这两个是等价的:

当我们在使用print的时候,实际上是调用了 sys.stdout.write(obj+'\n'),print在打印时会自动加个换行符。
这里就是一开始说的使用指定字符串长度的退格符

(7)我们使用asyncio.sleep函数来模拟IO操作。

(8)执行(16)的时候触发。

(9)(10)这两个是等价的,输出最后的显示结果。

(11)(12)这两句可以用(13)来替代使用asyncio.ensure_future(coroutine)

和 loop.create_task(coroutine)都可以创建一个task。

(14) 输出的是一个协程对象

(15)使用await把控制权交给主循环,以便loop调用其他的协程。

(16)Task对象可以取消,取消后会在协程当前暂停的yield处抛出asyncio.CancelledError异常。

(17)(18) asyncio.get_event_loop方法可以创建一个事件循环,

然后使用run_until_complete将协程注册到事件循环,并启动事件循环。协程的返回值是这次调用的返回值。

(19)结束循环。

参考资料:

流畅的python 第16章

关于asyncio的后续的一些使用请关注公众号:python学习开发。

转载地址:http://olfxa.baihongyu.com/

你可能感兴趣的文章
Nginx+mysql+php-fpm负载均衡配置实例
查看>>
shell脚本操作mysql数据库 (部份参考)
查看>>
MySql之基于ssl安全连接的主从复制
查看>>
informix的逻辑日志和物理日志分析
查看>>
VMware.Workstation Linux与windows实现文件夹共享
查看>>
ARM inlinehook小结
查看>>
wordpress admin https + nginx反向代理配置
查看>>
管理/var/spool/clientmqueue/下的大文件
查看>>
HTML学习笔记1—HTML基础
查看>>
mysql dba系统学习(20)mysql存储引擎MyISAM
查看>>
Win8转移应用商店的安装目录,用户目录
查看>>
centos 5.5 64 php imagick 模块错误处理记录
查看>>
apache中文url日志分析--php十六进制字符串转换
查看>>
Ansible--playbook介绍
查看>>
浅谈代理
查看>>
php创建桌面快捷方式实现方法
查看>>
基于jquery实现的超酷动画源码
查看>>
fl包下的TransitionManager的使用
查看>>
Factorialize a Number
查看>>
[USB-Blaster] Error (209040): Can't access JTAG chain
查看>>