摘要:记录一下await 关键字对于协程执行顺序的影响......

无意间看到了这个,原文链接 Python 的异步 IO:Asyncio 简介 - 止于至善 - SegmentFault 思否

await 关键字对于协程执行顺序的影响1.png

上面说的按我的理解是不对的,协程是否运行关键是这个协程是否被加入loop循环。
比如第一个例子:可以看到coro([3, 2, 1])这个协程是执行了的

import asyncio

async def coro(seq) -> list:
     """'IO' wait time is proportional to the max element."""
     print("开始执行")
     await asyncio.sleep(max(seq))
     print("结束运行")

async def main():
    # This is a bit redundant in the case of one task
    # We could use `await coro([3, 2, 1])` on its own
    t = asyncio.create_task(coro([3, 2, 1]))  # Python 3.7+
    print(f't: type {type(t)}')
    print(f't done: {t.done()}')

t = asyncio.run(main())

'''
运行结果:
t: type <class '_asyncio.Task'>
t done: False
开始执行
'''

第二个例子:

import asyncio

async def coro(seq) -> list:
     """'IO' wait time is proportional to the max element."""
     print("开始执行")
     await asyncio.sleep(max(seq))
     print("结束运行")

async def main():
    # This is a bit redundant in the case of one task
    # We could use `await coro([3, 2, 1])` on its own
    t = asyncio.create_task(coro([3, 2, 1]))  # Python 3.7+
    await t
    print(f't: type {type(t)}')
    print(f't done: {t.done()}')

t = asyncio.run(main())

'''
运行结果:
开始执行
结束运行
t: type <class '_asyncio.Task'>
t done: True
'''

这两个例子的区别就在于 t done: False 和 t done: True,将asyncio.run(main())创建的task命名为task1,t = asyncio.create_task(coro([3, 2, 1]))创建的task命名为task2。第一个例子中task1和task2是并列关系,所以当task1运行完后才运行task2(这个时候loop循环有task1和task2两个任务)......第二个例子中当执行完t = asyncio.create_task(coro([3, 2, 1]))这段代码后task1和task2也是并列关系,但是当执行完await t 后,task1和task2就变成了从属关系,task2执行完后才能执行task1(ps:我猜测这时候loop循环里面只有task2这一个任务,然后task1的__wakeup被设置成task2的回调函数,我猜的)

关于__wakeup的用法参考协程 await关键字 (三)