问题
代码如下:
import asyncio
import time
async def func1():
print('这里是func1-1')
await asyncio.sleep(3)
print('这里是func1-2')
async def func2():
print('这里是func2-1')
await asyncio.sleep(2)
print('这里是func2-2')
async def func3():
print('这里是func3-1')
await asyncio.sleep(4)
print('这里是func3-2')
async def main():
f1 = func1()
f2 = func2()
f3 = func3()
tasks = [
f1,f2,f3
]
await asyncio.wait(tasks)
if __name__ == '__main__':
t1 = time.time()
asyncio.run(main())
t2 = time.time()
print(t2-t1)
报错:
简单翻译一下:
禁止将协程对象直接传递给 wait()
这是因为python 3.11版本的新特性
解决
方法一:改动main()如下:
async def main():
async with asyncio.TaskGroup() as tg:
task1 = tg.create_task(func1())
task2 = tg.create_task(func2())
task3 = tg.create_task(func3())
运行结果:
方法二:
将with改成gather: asyncio.gather方法,与asyncio.wait方法类似,但更强大。如果列表中传入的不是create_task方法创建的协程任务,它会自动将函数封装成协程任务
`async def main():
f1 = func1()
f2 = func2()
f3 = func3()
tasks = [
f1,f2,f3
]
await asyncio.gather(*tasks)`
3.11 改动文档
下面附上3.11版本的改动示例,以作参考:
3.11版本以前写法:
import asyncio
import time
async def say_after(delay, what):
await asyncio.sleep(delay)
print(what)
async def main():
print(f"started at {time.strftime('%X')}")
await say_after(1, 'hello')
await say_after(2, 'world')
print(f"finished at {time.strftime('%X')}")
asyncio.run(main())
3.11版本写法:
async def main():
task1 = asyncio.create_task(
say_after(1, 'hello'))
task2 = asyncio.create_task(
say_after(2, 'world'))
print(f"started at {time.strftime('%X')}")
# Wait until both tasks are completed (should take
# around 2 seconds.)
await task1
await task2
print(f"finished at {time.strftime('%X')}")
3.11版本的替代简便写法:(官方推荐)
async def main():
async with asyncio.TaskGroup() as tg:
task1 = tg.create_task(
say_after(1, 'hello'))
task2 = tg.create_task(
say_after(2, 'world'))
print(f"started at {time.strftime('%X')}")
# The await is implicit when the context manager exits.
print(f"finished at {time.strftime('%X')}")