为什么我要使用`async def`而不是`@asyncio.coroutine`?

3

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

这不是关于这些类型之间的功能或实际差异的问题--这在这个StackOverflow答案中已经讨论过了。

我的问题是:我为什么要使用async def?它似乎没有比@asyncio.coroutine更多的优势,但却增加了额外的成本。

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

1
我删除了 syntax 标签并添加了 python 标签。通常情况下,您应该将 python 标签添加到所有 Python 相关的问题中,因为这是大多数人跟踪的标签。 - Dimitris Fasarakis Hilliard
1个回答

4

一个可能的答案由Martijn Pieters提供:

优点是,使用原生支持,您还可以引入其他语法以支持异步上下文管理器和迭代器。进入和退出上下文管理器,或循环遍历迭代器,可以成为协同程序中的更多点,表示其他代码可以再次运行,因为某些内容正在等待。

事实上,新的async withasync for语法已经实现了这一点,而这种“附加”解决方案(如装饰生成器)则无法轻松实现。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接