【问题标题】:Why would I ever want to use `async def` over `@asyncio.coroutine`?为什么我要使用 `async def` 而不是 `@asyncio.coroutine`?
【发布时间】:2017-03-27 10:29:56
【问题描述】:

Python 3.5 使用新的函数定义语法极大地扩展了对异步编程的支持。而异步函数以前只是“有好处的生成器”:

def generate_numbers():
    """
    Generator function that lazily returns 1 - 100
    """
    for i in range 100:
        yield i

generate_async = asyncio.coroutine(generate_numbers)
generate_async.__doc__ = """
    Coroutine that lazily returns 1 - 100
    This can be used interchangeably as a generator or a coroutine
    """

它们现在有自己的特殊声明语法和特殊行为,它们不再像通常的生成器函数那样使用:

aysnc def generate_async_native():
    """
    A coroutine that returns 1 - 100
    This CANNOT be used as a generator, and can ONLY be executed by running it from an event loop
    """
    for i in range(100):
        await i

不是关于这些类型之间的功能或实际差异的问题 - 在this StackOverflow answer 中进行了讨论。

我的问题是:我为什么要使用async def?与@asyncio.coroutine 相比,它似乎没有提供额外的好处,但却带来了额外的成本

  1. 破坏了向后兼容性(Python 3.5 代码与async def 在旧版本中甚至不会解析,尽管这可以说是一个特性而不是一个错误)和
  2. 似乎在调用函数方面提供的灵活性较低。

【问题讨论】:

  • 我删除了syntax 标签并添加了python 一个。一般来说,您应该将 python 标签添加到所有 python 问题中,因为这是大多数人跟踪的标签。

标签: python python-3.x asynchronous async-await backwards-compatibility


【解决方案1】:

Martijn Pieters给出了一个可能的答案:

优点是有了原生支持,您还可以引入额外的语法来支持异步上下文管理器和迭代器。进入和退出上下文管理器,或者在迭代器上循环然后可以成为协同例程中的更多点,表明其他代码可以运行,因为有东西再次等待

事实上,这已经通过新的async withasync for 语法实现了,这不能像修饰的生成器那样通过“附加”解决方案轻松实现。

【讨论】:

    猜你喜欢
    • 2017-03-27
    • 2012-03-04
    • 2018-04-17
    • 1970-01-01
    • 2013-12-07
    • 2017-11-07
    • 2016-08-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多