@ asyncio.coroutine与异步def

@ asyncio.coroutine与异步def,第1张

@ asyncio.coroutine与异步def

是的,使用

async def
语法的本地协程和使用
asyncio.coroutine
装饰器的基于生成程序的协程之间在功能上有所不同。

根据PEP 492引入的

async def
语法:

  1. 原生协程 对象不实现
    __iter__

    __next__
    方法。因此,它们不能被遍历或传递给
    iter()
    list()
    tuple()
    和其他内置插件。它们也不能
    for..in
    循环使用。

尝试在本机协程对象上使用

__iter__
__next__
对本机协程对象进行尝试将导致TypeError。

  1. 普通生成器 无法 生成

    yield from
    本地协程 :这样做将导致TypeError。

  2. 基于生成器的协程 (对于异步代码必须用修饰

    @asyncio.coroutine
    )可以
    yield from
    原生协程对象

  3. inspect.isgenerator()
    inspect.isgeneratorfunction()
    返回
    False

    原生协程 对象和 原生协程功能

上面的要点1表示,虽然使用

@asyncio.coroutine
装饰器语法定义的协程函数可以像传统的生成器函数一样工作,但使用该语法定义的协程函数
asyncdef
不能。

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

import [email protected] decorated(x):    yield from xasync def native(x):    await x

尽管这两个函数的字节码几乎相同:

>>> import dis>>> dis.dis(decorated)  50 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)  80 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_ITER
vs
GET_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
语法进行了更详细的研究:异步/等待在Python
3.5中如何工作?
涵盖了更深层次的差异。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5653587.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存