为什么我会想在 `@asyncio.coroutine` 上使用 `async def`?
Why would I ever want to use `async def` over `@asyncio.coroutine`?
Python 3.5 使用新的函数定义语法极大地扩展了对异步编程的支持。而异步函数以前只是 "generators with benefits":
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
这是而不是关于这些类型之间的功能或实际差异的问题——在中讨论.
我的问题是:我为什么要使用 async def
?与 @asyncio.coroutine
相比,它似乎没有提供额外的好处,但会增加额外的成本,因为它
- 打破了向后兼容性(Python 3.5 代码与
async def
在旧版本中甚至不会 parse,尽管这可以说是一个功能而不是错误)和
- 似乎在调用函数方面提供的灵活性较低。
给出了一个可能的答案:
The advantages are that with native support, you can also introduce additional syntax to support asynchronous context managers and iterators. Entering and exiting a context manager, or looping over an iterator then can become more points in your co-routine that signal that other code can run instead because something is waiting again
这实际上已经通过新的 async with
和 async for
语法实现了,这不能像装饰生成器那样使用 "tack-on" 解决方案那么容易实现。
Python 3.5 使用新的函数定义语法极大地扩展了对异步编程的支持。而异步函数以前只是 "generators with benefits":
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
这是而不是关于这些类型之间的功能或实际差异的问题——在
我的问题是:我为什么要使用 async def
?与 @asyncio.coroutine
相比,它似乎没有提供额外的好处,但会增加额外的成本,因为它
- 打破了向后兼容性(Python 3.5 代码与
async def
在旧版本中甚至不会 parse,尽管这可以说是一个功能而不是错误)和 - 似乎在调用函数方面提供的灵活性较低。
The advantages are that with native support, you can also introduce additional syntax to support asynchronous context managers and iterators. Entering and exiting a context manager, or looping over an iterator then can become more points in your co-routine that signal that other code can run instead because something is waiting again
这实际上已经通过新的 async with
和 async for
语法实现了,这不能像装饰生成器那样使用 "tack-on" 解决方案那么容易实现。