gpt4 book ai didi

python - @asyncio.coroutine 与 async def

转载 作者:IT老高 更新时间:2023-10-28 21:44:59 26 4
gpt4 key购买 nike

使用我见过的 asyncio 库,

@asyncio.coroutine
def function():
...

async def function():
...

可以互换使用。

两者在功能上有区别吗?

最佳答案

是的,使用 async def 语法的原生协程和使用 asyncio.coroutine 装饰器的基于生成器的协程之间存在功能差异。

根据PEP 492 ,其中引入了 async def 语法:

  1. Native coroutine objects do not implement __iter__ and __next__ methods. Therefore, they cannot be iterated over or passed to iter(), list(), tuple() and other built-ins. They also cannot be used in a for..in loop.

    An attempt to use __iter__ or __next__ on a native coroutine object will result in a TypeError .

  2. Plain generators cannot yield from native coroutines: doing so will result in a TypeError .

  3. generator-based coroutines (for asyncio code must be decorated with @asyncio.coroutine) can yield from native coroutine objects.

  4. inspect.isgenerator() and inspect.isgeneratorfunction() return False for native coroutine objects and native coroutine functions.

上面的第 1 点意味着虽然使用 @asyncio.coroutine 装饰器语法定义的协程函数可以像传统的生成器函数一样运行,但使用 async def 语法定义的协程函数则不能。

这里有两个最小的,表面上等效的协程函数,用两种语法定义:

import asyncio

@asyncio.coroutine
def decorated(x):
yield from x

async def native(x):
await x

虽然这两个函数的字节码几乎相同:

>>> import dis
>>> dis.dis(decorated)
5 0 LOAD_FAST 0 (x)
3 GET_YIELD_FROM_ITER
4 LOAD_CONST 0 (None)
7 YIELD_FROM
8 POP_TOP
9 LOAD_CONST 0 (None)
12 RETURN_VALUE
>>> dis.dis(native)
8 0 LOAD_FAST 0 (x)
3 GET_AWAITABLE
4 LOAD_CONST 0 (None)
7 YIELD_FROM
8 POP_TOP
9 LOAD_CONST 0 (None)
12 RETURN_VALUE

...唯一的区别是 GET_YIELD_FROM_ITERGET_AWAITABLE,当尝试迭代它们返回的对象时,它们的行为完全不同:

>>> list(decorated('foo'))
['f', 'o', 'o']

>>> list(native('foo'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'coroutine' object is not iterable

显然 'foo' 不是可等待的,因此尝试用它调用 native() 没有多大意义,但希望这一点很清楚它返回的 coroutine 对象是不可迭代的,不管它的参数是什么。

Brett Cannon 对 async/await 语法的更详细调查:How the heck does async/await work in Python 3.5?更深入地涵盖了这种差异。

关于python - @asyncio.coroutine 与 async def,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40571786/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com