注意:Future 是一种低级类型,因此,如果不是库/框架开发人员,则无需过多考虑它 。
协程协程属于可等待对象,因此可以在其他协程中被等待 。协程中两个重要的概念:协程函数,定义为async def的函数 。
协程对象:通过调用协程函数所返回的对象 。
asyncio基于生成器的协程函数修饰函数定义的函数将被async/await语法取代,但将继续支持,直到Python 3.10
任务任务用于同时安排协同程序 。所有异步应用程序通常(至少)具有单个"主"入口点任务,该任务将安排在事件循环上立即运行 。这是使用asyncio.run函数完成的 。
协同例程函数预计将传递给asyncio.run,而内部异步将使用帮助器函数coroutines.iscoroutine检查该函数 。如果不是协同程序,则引发错误,否则协同例程将传递给 loop.run_until_complete
run_until_complete函数需要一个Future,并使用另一个帮助futures.isfuture函数来检查提供的类型 。如果检查不是Future,则低级 API ensure_future用于将协同例程转换为 Future 。
在旧版本的 Python 中,如果要手动创建自己的 Future 并将其安排到事件循环上,那么就要使用asyncio.ensure_future(现在被视为低级 API),但使用 Python 3.7+ 时,它被asyncio.create_task所取代 。
另外使用 Python 3.7,直接与事件循环交互(例如获取事件循环、创建任务并将其传递到事件循环)的函数已被替换为create_taskasyncio.run 。
我们可以通过下面的 API 查看在事件循环上运行的任务的状态:
asyncio.current_task
asyncio.all_tasks
FutureFuture 是一个低级await对象,表示异步操作的最终结果 。该 API 的存在是为了启用基于回调的代码与async/await一起使用,而loop.run_in_executor是返回 Future 的异步低级 API 函数的示例 。
异步编程实例运行异步程序高级 API(根据 Python 3.7+)是:
import asyncioasync def foo():print("Foo!")async def hello_cc():await foo() # waits for `foo()` to completeprint("Hello Chongchong!")asyncio.run(hello_world()).run函数始终创建新的事件循环并在末尾关闭它 。如果使用的是较低级别的 API,则必须手动处理该API:
loop = asyncio.get_event_loop()loop.run_until_complete(hello_cc())loop.close()在 REPL 中运行异步代码在 Python 3.8 之前,我们无法在标准 Python REPL 中执行异步代码(需要改用 IPython REPL) 。
要使用最新版本的 Python 执行此操作,运行python -m asyncio。REPL 启动后,就无需再使用asyncio.run(),只需直接使用await语句 。
[Clang 10.0.1 (clang-1001.0.46.4)] on darwinUse "await" directly instead of "asyncio.run()".Type "help", "copyright", "credits" or "license" for more information.>>> import asyncio>>> async def foo():... await asyncio.sleep(5)... print("done")...>>> await foo()done请注意,REPL 在启动时会自动执行import asyncio,因此我们可以使用任何asyncio函数(如.sleep函数),而无需自行手动键入导入语句 。
使用其他事件循环模块如果由于种种原因我们不想使用asyncio提供的事件循环(这是纯 Python 实现),则可以将其交换为另一个事件循环,如uvloop 。
uvloop 是内置异步事件循环的快速回放替换 。uvloop 在中实现,在引擎中使用libuv 。根据uvloop的作者基准测试,它在执行性能上可堪比golang 。

文章插图
uvloop的使用也很简单,先使用pip install uvloop 安装,然后添加一个uvloop.install()调用,如下所示:
import asyncioimport uvloopasync def foo():print("Foo!")async def hello_cc():await foo()print("Hello Chongchong!")uvloop.install()asyncio.run(hello_cc())并发函数以下函数有助于协调同时运行函数,并提供根据应用程序需求的不同控制 。asyncio.gather:获取一系列可等待值,返回成功等待的值的聚合列表 。
asyncio.shield:防止取消可等待的对象 。
asyncio.wait:等待一系列可等待,直到满足给定的"条件" 。
asyncio.wait_for:等待单个等待,直到达到给定的"超时" 。
asyncio.as_completed: 类似于gather,但返回在结果准备就绪时填充的 Future 。
注意:gather有处理错误和取消的特定选项 。例如,return_exceptions: False如果随后由其中一个可等待项引发的第一个异常返回到 gather的调用方,其中似乎设置为True,则异常将连同成功结果一起在列表中聚合 。如果gather()
被取消,所有提交的等待(尚未完成)也将被取消 。
推荐阅读
- OpenCV-dlib-python3实现人脸戴墨镜和含Y的抖音效果
- python高准确率滑动验证破解平台,提供免费api接口,解决反爬虫
- 给Python代码加上酷炫进度条的几种姿势
- python列表和元组,到底用哪一个?
- 总结 90 条写 Python 程序的建议
- 用 Python 实现每秒处理 120 万次 HTTP 请求
- 详细一看就懂得Python包概念
- 如何在 Mac 上使用 pyenv 运行多个版本的 Python | Linux 中国
- Python自动化 如何优雅的操作数据库?
- 利用python爬取并翻译GEO数据库
