已弃用函数@asyncio.coroutine: Python 3.10删除async def了
asyncio.sleep:将在 Python 3.10 中删除参数loop
注意:这些大多数这些 API 中都使用了一个参数参数loop,让其指示要使用的特定事件循环 。Python 3.8 中已经弃用了该参数,并计划在 3.10 中完全删除它 。
gather下面的示例演示如何等待多个异步任务完成 。
import asyncioasync def foo(n):await asyncio.sleep(5) # wait 5s before continuingprint(f"n: {n}!")async def main():tasks = [foo(1), foo(2), foo(3)]await asyncio.gather(*tasks)asyncio.run(main())
wait下面的示例使用FIRST_COMPLETED选项,表示无论任务首先完成什么,都将返回什么 。
import asynciofrom random import randrangeasync def foo(n):s = randrange(5)print(f"{n} will sleep for: {s} seconds")await asyncio.sleep(s)print(f"n: {n}!")async def main():tasks = [foo(1), foo(2), foo(3)]result = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)print(result)asyncio.run(main())
此程序的示例输出是:
1 will sleep for: 4 seconds2 will sleep for: 2 seconds3 will sleep for: 1 secondsn: 3!({<Task finished coro=<foo() done, defined at await.py:5> result=None>}, {<Task pending coro=<foo() running at await.py:8> wait_for=<Future pending cb=[<TaskWakeupMethWrApper object at 0x10322b468>()]>>, <Task pending coro=<foo() running at await.py:8> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x10322b4c8>()]>>})
wait_for下面的示例演示如何利用超时来防止无休止地等待异步任务完成 。
import asyncioasync def foo(n):await asyncio.sleep(10)print(f"n: {n}!")async def main():try:await asyncio.wait_for(foo(1), timeout=5)except asyncio.TimeoutError:print("timeout!")asyncio.run(main())
注意: asyncio.TimeoutError不提供任何额外信息,因此尝试在输出中使用它没有意义(例如 except asyncio.TimeoutError as err: print(err)) 。
as_completed下面的示例演示如何as_complete生成要完成的第一个任务,然后是下一个最快任务,下一个任务在完成之前 。
import asynciofrom random import randrangeasync def foo(n):s = randrange(10)print(f"{n} will sleep for: {s} seconds")await asyncio.sleep(s)return f"{n}!"async def main():counter = 0tasks = [foo("a"), foo("b"), foo("c")]for future in asyncio.as_completed(tasks):n = "quickest" if counter == 0 else "next quickest"counter += 1result = await futureprint(f"the {n} result was: {result}")asyncio.run(main())
此程序的示例输出是:
c will sleep for: 9 secondsa will sleep for: 1 secondsb will sleep for: 0 secondsthe quickest result was: b!the next quickest result was: a!the next quickest result was: c!
create_task下面的示例演示如何将协同例程转换为任务并将其安排到事件循环上 。
import asyncioasync def foo():await asyncio.sleep(10)print("Foo!")async def hello_cc():task = asyncio.create_task(foo())print(task)await asyncio.sleep(5)print("Hello Chongchong!")await asyncio.sleep(10)print(task)asyncio.run(hello_cc())
从上面的程序中我们可以看到,我们用create_task将协同例程函数转换为任务 。这将自动安排在下一个可用刻度处在事件循环上运行的任务 。
这与较低级别的 API ensure_future(这是创建新任务的首选方法)不同 。ensure_future函数具有特定的逻辑分支,使其可用于更多的输入类型,而不是create_task仅支持将协同例程排到事件循环中并将其包装到任务中(请参阅:ensure_future源代码) 。
此程序的输出将是:
<Task pending coro=<foo() running at create_task.py:4>>Hello Chongchong!Foo!<Task finished coro=<foo() done, defined at create_task.py:4> result=None>
让我们回顾一下代码,并比较我们可以看到的上述输出...
我们将转换foo()到任务,然后在创建任务后立即打印返回的任务 。因此,当我们打印任务时,我们可以看到其状态显示为"挂起"(因为它尚未执行) 。
接下来,我们将sleep五秒钟,因为这将导致foo任务现在运行(因为当前任务hello_world将被视为繁忙) 。
在foo任务中,我们也处于sleep状态,但时间比hello_world长,因此事件循环现在上下文将切换回hello_world任务,在睡眠时将传递该任务,我们将打印输出字符串 Hello Chongchong 。
最后,我们又sleep十秒钟 。这只是为了我们可以给foo任务足够的时间来完成和打印自己的输出 。如果我们不这样做,那么hello_world任务将完成并关闭事件循环 。最后一行hello_world是打印foo任务,我们将看到foo任务的状态现在将显示为"已完成" 。
推荐阅读
- OpenCV-dlib-python3实现人脸戴墨镜和含Y的抖音效果
- python高准确率滑动验证破解平台,提供免费api接口,解决反爬虫
- 给Python代码加上酷炫进度条的几种姿势
- python列表和元组,到底用哪一个?
- 总结 90 条写 Python 程序的建议
- 用 Python 实现每秒处理 120 万次 HTTP 请求
- 详细一看就懂得Python包概念
- 如何在 Mac 上使用 pyenv 运行多个版本的 Python | Linux 中国
- Python自动化 如何优雅的操作数据库?
- 利用python爬取并翻译GEO数据库