asyncio 中所有这些已弃用的“循环”参数是啥?
Posted
技术标签:
【中文标题】asyncio 中所有这些已弃用的“循环”参数是啥?【英文标题】:What are all these deprecated "loop" parameters in asyncio?asyncio 中所有这些已弃用的“循环”参数是什么? 【发布时间】:2020-02-20 03:11:52 【问题描述】:asyncio
中的许多函数已弃用 loop
参数,计划在 Python 3.10 中删除。示例包括 as_completed()
、sleep()
和 wait()
。
我正在寻找有关这些参数及其删除的一些历史背景。
loop
解决了哪些问题?为什么一开始会使用它?
loop
出了什么问题?为什么会被大量删除?
loop
消失了,用什么代替?
【问题讨论】:
您的问题措辞不同,但在此回答 ***.com/questions/40340493/… - 您不再需要/获得通过特定事件循环。 我不觉得我的“发生了什么以及为什么”的问题在那里得到了回答。我基本上阅读了另一个问题,它的 cmets 和它的答案,告诉我该怎么做,没有太多的理由。 (基本上,我首先要重申的弃用警告。) 该答案中链接的文章从字面上回答了您的问题mail.python.org/pipermail/async-sig/2016-November/000171.html - 发生了什么 = 全局事件循环导致问题,为什么会发生 = 糟糕的设计决策,出了什么问题 = 循环是为了传递全局循环,取代它的东西 = 什么都没有,它仍然存在,但你不再需要传递它(解决许多问题),如果你需要它,你可以将它作为current_event_loop()
@Grismar 我的问题的答案很可能在那篇文章中,但它不在链接到那篇文章的 Stack Overflow 答案中!我也不希望它是 - 这两个问题谈论的是同一件事,但我所问的是不同的。
【参考方案1】:
loop
解决了哪些问题?为什么一开始会使用它?
在 Python 3.6 之前,asyncio.get_event_loop()
不能保证在从异步协程或回调调用时返回当前正在运行的事件循环。它将返回之前使用 set_event_loop(some_loop)
设置的任何事件循环,或者由 asyncio 自动创建的事件循环。但是同步代码可以很容易地使用another_loop = asyncio.new_event_loop()
创建一个不同的循环,并使用another_loop.run_until_complete(some_coroutine())
启动它。在这种情况下,get_event_loop()
在some_coroutine
内部调用,它等待的协程将返回some_loop
而不是another_loop
。这种事情在随便使用 asyncio 时不会发生,但它必须由 async 库来解释,它不能假设它们是在默认事件循环下运行的。 (例如,在测试或涉及线程的某些用法中,可能希望启动一个事件循环而不用set_event_loop
干扰全局设置。)库将提供显式loop
参数,您将在其中传递@987654338 @ 在上述情况下,当运行循环与使用 asyncio.set_event_loop()
设置的循环不同时,您将使用它。
此问题在 Python 3.6 和 3.5.3 中为 fixed,其中 get_event_loop()
已修改为在从内部调用时可靠地返回运行循环,在上述情况下返回 another_loop
。 Python 3.7 将另外引入get_running_loop()
,它完全忽略全局设置并始终返回当前正在运行的循环,如果不在循环内部,则会引发异常。有关原始讨论,请参阅this thread。
一旦get_event_loop()
变得可靠,另一个问题就是性能问题。由于一些非常频繁使用的调用需要事件循环,尤其是call_soon
,因此传递和缓存循环对象更有效。 Asyncio 本身就是这样做的,许多库也纷纷效仿。最终get_event_loop()
变成了accelerated in C,不再是瓶颈。
这两个更改使loop
参数变得多余。
loop
出了什么问题?为什么会被大量删除?
与任何其他冗余一样,它会使 API 复杂化并带来错误的可能性。异步代码几乎从不只是随机地与不同的循环通信,现在get_event_loop()
既正确又快速,没有理由不使用它。
此外,将循环传递到典型应用程序的所有抽象层非常乏味。随着 async/await 成为其他语言的主流,很明显手动传播全局对象不符合人体工程学,程序员不应要求这样做。
loop
已经不存在了,用什么替代它?
只需在需要时使用get_event_loop()
获取循环。或者,您可以使用get_running_loop()
断言循环正在运行。
在 Python 3.7 中访问事件循环的需求有所减少,因为一些以前只能作为循环方法使用的函数,例如 create_task
,现在可以作为独立函数使用。
【讨论】:
【参考方案2】:loop
参数是传递全局事件循环的方法。相同功能的新实现不再需要您传递全局事件循环,它们只需在需要的地方请求它。
正如文档所建议的 https://docs.python.org/3/library/asyncio-eventloop.html:“应用程序开发人员通常应该使用高级 asyncio 函数,例如 asyncio.run(),并且应该很少需要引用循环对象或调用其方法。”
消除将其传递给库函数的需要符合该原则。循环不会被替换,但它的消失仅仅意味着您不再需要“手动”处理它。
【讨论】:
以上是关于asyncio 中所有这些已弃用的“循环”参数是啥?的主要内容,如果未能解决你的问题,请参考以下文章
图像中已弃用的 Notification 类的替代方法是啥?
管理 Firebase 安装实施的截止日期是啥时候?移动应用中已弃用的 Firebase 安装 ID 有啥影响?
已弃用的 Hibernate.createClob(Reader reader, int length) 的替代方法是啥