@ asyncio.coroutine与异步def

发布于 2021-01-29 18:22:44

asyncio我看过的图书馆

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

async def function():
    ...

可互换使用。

两者之间有功能上的区别吗?

关注者
0
被浏览
52
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    是的,使用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装饰器语法定义的协程函数可以像传统的生成器函数一样工作,但使用该语法定义的协程函数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_ITERvs 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中如何工作?
    涵盖了更深层次的差异。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看