python 的 async, await(协程)理解
python中的async/await and yield 以及yield from 的概念
首先说明以下:
① yield from 诞生于python3.3版本
② async/await 关键字 诞生于python3.5版本
以上两种都可以称为协程,也就是异步的实现方式之一。
我的版本为python3.6
一、yield from
首先最简单最原始的一种协程关键字
1.yield:等价于return,只不过yield具备惰性特性,惰性特性,有效的节省内存控件,当需要输出的时候才会输出。存在yield关键字的函数,被称作生成器函数。
2.yield from :yield关键字的升级版,后面可以接任何的可迭代对象(和下面的await有区别哦,下面会讲),表示要从哪里generate 元素出来,yield from generate,返回一个生成器。
例子:
1 | |
结果:
1 | |
注:yield from相当于一层for循环,它会处理最后的异常StopIteration,如果函数中有return返回的话(需要next()显示抛出异常),通过yield from 会隐式处理该异常,因此并不会输出return 后的内容。因此如果要输入return 后的内容,则需要手动不断next()了~
最后for循环print(i),会内部循环调用next()方法,同时最后处理StopIteration异常。
在《流畅的python》一书中这样介绍了yield from:
选择书中的一幅图
{width=”100%”}
解释:
1.委派生成器在 yield from 表达式处暂停时,调用方可以直接把数据发给子生成器。
2.子生成器再把产出的值发给调用方。
3.子生成器返回之后,解释器会抛出 StopIteration 异常,并把返回值附加到异常对象上,此时委派生成器会恢复。
yield from 的主要作用:
是打开双向通道,把最外层的调用方与最内层的子生成器连接起来,这样二者可以直接发送和产出值,还可以直接传入异常,而不用在位于中间的协程中添加大量处理异常的样板代码。
二、async/await
async/await是一套的关键字,也就是他们俩一般一起使用。
async:用来声明一个函数为异步函数的关键字。
await:用来对程序进行挂起,转到其他异步程序中执行。然后执行完(也可能另外的异步程序也需要挂起)
简单的做菜小案例:
1 | |
运行结果:
1 | |
说明:
上述例子可以发现,采用异步执行只花了11s就做好了一顿饭,而如果我们采用同步执行,我们需要花费10+8+11=29s,快了一倍多。因为,我在做淘完米后,我就可以去洗菜,而不是在那一直等米饭熟。
注:
① 使用async关键字修饰的函数为指明为异步函数,执行到await将当前执行的程序挂起来,不经过系统调用切换到其他函数进行执行(这是与线程区别不同之一)。
② 这里使用了async.sleep(),而不是time.sleep(),因为async.sleep()的时间是可等待的,也就是”假睡眠”,可以进行函数间的切换而time.sleep()是真睡眠。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!