异步中所有这些不赞成使用的“循环”参数是什么?

发布于 2021-01-29 17:16:33

其中的许多函数asyncio均已弃用loop参数,计划在Python
3.10中将其删除。实例包括as_completed()sleep(),和wait()

我正在寻找有关这些参数及其删除的一些历史背景。

  • loop解决了什么问题?为什么首先要使用它?
  • 怎么了loop?为什么将其大规模删除?
  • 什么取代了loop,现在它消失了?
关注者
0
被浏览
181
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    loop解决了什么问题?为什么首先要使用它?

    在Python
    3.6之前,asyncio.get_event_loop()从asyncio协程或回调调用时,不能保证返回当前正在运行的事件循环。它会返回先前使用设置的任何事件循环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时不会发生这种情况,但是必须由异步库解决,该库不能假定它们在默认事件循环下运行。(例如,在测试或某些涉及线程的用法中,您可能希望启动事件循环而不用打扰到全局设置set_event_loop。)这些库将提供显式loop参数,以供您another_loop在上述情况下进行传递,以及只要正在运行的循环不同于用设置的循环,就可以使用asyncio.set_event_loop()

    此问题将在Python 3.6和3.5.3中修复,在Python
    3.6和3.5.3中get_event_loop()已进行了修改,可以可靠地返回运行循环(如果从内部调用),并another_loop在上述情况下返回。Python
    3.7将另外引入get_running_loop(),它会完全忽略全局设置,并始终返回当前正在运行的循环,如果不在其中,则会引发异常。有关原始讨论,请参见此主题

    一旦get_event_loop()变得可靠,另一个问题就是性能。由于某些非常频繁使用的调用需要事件循环call_soon,因此,传递和缓存循环对象的效率更高。Asyncio本身就是这样做的,许多库也纷纷效仿。最后get_event_loop()用C加速和不再是一个瓶颈。

    这两个更改使loop参数变得多余。

    怎么了loop?为什么将其大规模删除?

    与其他任何冗余一样,它使API复杂化,并为出错提供了可能性。异步代码几乎 永远不
    应该只是随机地与不同的循环通信,而现在这get_event_loop()既正确又快速,没有理由不使用它。

    同样,将循环遍历典型应用程序的所有抽象层也很繁琐。随着async /
    await在其他语言中成为主流,很明显,手动传播全局对象已不再符合人体工程学,并且程序员也不需要这样做。

    什么取代了loop,现在它消失了?

    只需get_event_loop()在需要时使用它即可获得循环。另外,您可以get_running_loop()用来断言循环正在运行。

    在Python 3.7中,访问事件循环的需要有所减少,因为某些以前只能作为循环方法使用的函数(例如)create_task现在可以作为独立函数使用。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看