什么算协程 (Coroutines)
通过 async/await 语法进行声明
可等待对象 (Awaitables)
如果一个对象可以在 await 语句中使用,那么它就是可等待对象
可等待对象有三种主要类型:协程(我觉得这是指协程函数),Task,Future
(换言之,如果一个对象是协程,想要在其他协程函数中调用,就必须用await 修饰)
协程: 可用来表示两个紧密相连的概念
协程函数:定义形式为 async def 的函数
协程对象:调用协程函数所返回的对像
import asyncio
async def say_after(delay,word):
await asyncio.sleep(delay)
print(word)
async def main():
await say_after(1,‘hello')
asymcio.run(main())
任务: 被用来并发执行协程
当一个协程通过asyncio.create_task()/3loop.cneate_task()来创建Task对象,该协程将自动排入日程准备立即运行
async def sayafter(delay.word):
await asyncio.sleep(delay)
print(word)
async def main():
task1 = asyncio.create_task(say after(1,hello'))
await task1
asyncio.run(main())
Future: 是一种特殊的低层级可等待对象,表示一个异步操作的最终结果 。(我理解的,在Python3.7以后,就不怎么用了
在 asyncio 中需要Future对象以便允许通过async/await使用基于回调的代码。
运行asyncio程序
asyncio.run(coro,debug=False)
执行 coroutine coro 并返回结果。
此函数总是会创建一个新的事件循环并在结束时关闭。是程序的主入口点
创建任务
asyncio.create_task(coro,*,name=None)
将core协程 打包为一个Task 以准备执行。返回 Task 对象
如果name 不为 None,它将使用 Task.set name()来设为任务的名称。
!!! 创建任务对象,是为了可以并发的执行多个协程任务
此函数在 Python 3.7 中被加入。在 Python 3.7 之前,可以改用低层级的 asyncio.ensure_future() 函数
休眠
asyncio.sleep(delay,result=True,*,loop=None)
阻塞delay指定的秒数,返回一个协程
如果指定了result,则当协程完成时将其返回给调用者
sleep()总是会挂起当前任务,以允许其他任务运行。
并发运行任务 (这是重点)
asyncio.gather(*aws, loop=None, return_exceptions=False)
并发运行 aws中的可等待对象,aws是一个序列(列表,元组等),*不能省略。返回一个可等待对象
1.如果aws中的某个可等待对象为协程,它将自动作为一个task执行,省去了 create_task()的步骤
2.如果所有可等待对象都成功完成,结果将是一个由所有返回值聚合而成的列表(前提是被执行函数有返回值)结果值的顺序与 aws 中可等待对象的顺序一致(可以一次获取全部返回值,相当于[task1.result(),task2.result(),...](这个很实用的。网上搜了好多怎么接收aysncio返回值的方法,都还停留在 Future 阶段,已经out了)
3.如果return_exceptions 为 False(默认),所引发的首个异常会立即传给等待 gather()的任务、aws 序列中的其他可等待对象 不会被取消,并将继续运行
4.如果 return exceptions 为 True,异常会和成功的结果一样处理,并聚合至结果列表。(return_exceptions 没有试出来差异)
5.如果gather被取消,所有被提交(未完成的)的可等待对象也会被取消
6.如果aws序列中的任一task或future对象被取消,将引发CanceIledError,但是gather不会被取消,其他tasks/future将继续执行
屏蔽取消操作
aysnico.shield(aw,*,loop=None)
返回一个可等待对象
保护一个可等待对象,防止其被取消
如果aw是一个协程,它也会自动转为task
超时
asyncio.wait_for(aw,timeout,*,loop=None)
aw is an awaitable,返回一个协程
当aw为协程时,同样可以自动转为task(这已经出现第三次了,瞬间感觉create_task()这一步鸡肋了。)
等待av可等待对象完成,指定timeout秒数后超时。如果 timeout为 None,则等待直到完成.如果超时了,task会被终止,并且报错 asyncio.TimeoutError
为了避免超时被终止,可以将task打包到shield()方法里。(可以防止网页加载过慢》
简单等待
ayancio.wait(aws,",loop=None,timeout=None,return_when=ALL_COMPLETED)
aws is a list of awaitables,返回一个协程
并发运行aws 指定的 可等待对象 并阻塞线程直到满足 return_when 指定的条件。返回两个 Task/Future 集合:(done,pending).
与 wait_for()不同,wait()在超时发生时不会取消可等待对象
内省(不懂这个词是什么意思)
asyncio.current_task(loop=None)
返回当前运行的task实例,如果没有正在运行的任务,则返回None.
asyncio.all_tasks(loop=None)
返回事件循环所运行的未完成的task对象的集合
返回一个事件循环中所有任务的集合(到底是所有,还是未完成的)
如果loop=Mone,则会使用get_running_loop()获取当前时间循环
Task对象
通过asyncio.creste_task()/loop.create_task()来创建Task对象
task.cancel() 请求取消Task对象
task.cancelled 如果 Task 对象 被取消 则返回True
task.done()如果 Task 对象 已完成 则返回True
task.result()返回 Task 的结果 (这个就是接收被执行函数的返回值的)
Future对象 (3.7后基本用不到)
asvncio.isfuture(obj)
如果obj是以下任意对象,则返回True