一个有趣的小例子,带你入门协程模块-asyncio

上篇文章写了关于yield from的用法,简单的了解异步模式,【https://www.cnblogs.com/c-x-a/p/10106031.html】这次让我们通过一个有趣例子带大家了解asyncio基本使用。

目标效果图

基本原理

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 asyncio
import itertools
import sys
import time
async 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 result def 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学习开发。

一个有趣的小例子,带你入门协程模块-asyncio的更多相关文章

  1. 一个少女心满满的例子带你入门canvas

    https://blog.csdn.net/sunshine940326/article/details/76572850 本文首发于我的个人博客:http://cherryblog.site/ gi ...

  2. [python]python 遍历一个list 的小例子:

    [python]python 遍历一个list 的小例子: mlist=["aaa","bbb","ccc"]for ss in enume ...

  3. Unity带参数的协程

    两种方法都可以传递参数,代码如下: using UnityEngine; using System.Collections; public class Test : MonoBehaviour { v ...

  4. Python并发编程之从生成器使用入门协程(七)

    大家好,并发编程 进入第七篇. 从今天开始,我们将开始进入Python的难点,那就是协程. 为了写明白协程的知识点,我查阅了网上的很多相关资料.发现很难有一个讲得系统,讲得全面的文章,导致我们在学习的 ...

  5. go语言从例子开始之Example21.协程

    Go 协程 在执行上来说是轻量级的线程. golang使用协程用go关键字.后边正常调用函数. Example: package main import "fmt" func ak ...

  6. Python入门(一个有趣的画图例子实战)你肯定不会

    前言本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:qiu_fang  画一条可爱的python(蟒蛇): import t ...

  7. 一个简单的小例子让你明白c#中的委托-终于懂了!

    模拟主持人发布一个问题,由多个嘉宾来回答这个问题. 分析:从需求中抽出Host (主持人) 类和Guests (嘉宾) 类. 作为问题的发布者,Host不知道问题如何解答.因此它只能发布这个事件,将事 ...

  8. c++ 内存分配中一个有趣的小问题

    以下代码测试环境:vs2019 执行这么一段代码,看看会发生什么. int main() { ] = { }; arr[] = ; } 毫无疑问,会报错,因为访问越界了. 再看看另一段代码 ] = { ...

  9. 一个Java线程小例子(仿火车票售卖)

    public class MyThread extends Thread{ private static int ticket=100; public void run(){ for(int i=0; ...

随机推荐

  1. luogu2024 食物链 (并查集)

    把一个点拆成三个,分别对应它的同类.它的猎物和它的天敌,这样的话(以下的相等都是并查集意义上的): 如果令a,b同类,那么a的猎物不能是b的同类,a的天敌不能是b的同类 如果令a吃b,那么a的同类不能 ...

  2. P1382 楼房 set用法小结

    这个sb题目,剧毒... STL大法好 首先,我准备用经典的线段树优化扫描线来做.之前的矩形周长把我困了数天导致我胸有成竹. 然后,敲代码半小时,调试半个月......这个,sb,怎么改都是0分+2个 ...

  3. springboot 读取 resource文件

    文件位置信息如图: import java.io.IOException; import java.io.InputStream; import java.net.URLEncoder; import ...

  4. Makefile ------ 在Makefile中进行宏定义-D

    在Makefile中我们可以通过宏定义来控制源程序的编译.只要在Makefile中的CFLAGS(变量名随意)中通过选项-D来指定你于定义的宏即可. 如:CFLAGS += -D _YUQIANG在编 ...

  5. 2018acm-icpc西安邀请赛后记

    第一次参加icpc的邀请赛,有一点小激动,深知大一弱队实力弱,赛前给队友的目标就是拿块铜,不打铁. 热身赛因为没有用过pc^2,codeblocks又用不习惯的原因,开始调工程调了很久,差一点拿到A题 ...

  6. Hadoop生态圈-通过CDH5.15.1部署spark1.6与spark2.3.0的版本兼容运行

    Hadoop生态圈-通过CDH5.15.1部署spark1.6与spark2.3.0的版本兼容运行 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在我的CDH5.15.1集群中,默 ...

  7. Linux下Shell去除空行的方法

    1.用grep命令 grep -v “^$” 文件名 2.用sed命令 cat 文件名 | sed ‘/^$/d' 3.用awk命令 cat 文件名 | awk ‘{if($0!=”")pr ...

  8. JAVA记录-基础常识

    1.==与equals区别 1)==用于基本数据类型的比较,判断引用是否指向堆内存的同一地址.---引用地址 2)equals用于判断两个变量是否是对同一对象的引用,即堆中的内容是否相同,返回值为布尔 ...

  9. java AOP使用配置项来进行注入实践

    java AOP使用注解@annotation方式实践 场景: 在目标方法前面和后面执行通知方法 目标类 @Component public class Play { public void watc ...

  10. awk词频统计功能

    [root@test88 ~]# vim word_freq.sh #!/bin/bash if [ $# -ne 1 ];then echo "Usage: $0 filename&quo ...