为什么我们需要asyncio.coroutine装饰器?

时间:2017-11-05 10:57:17

标签: python python-asyncio coroutine

为什么我们需要asyncio.coroutine装饰器?它提供了什么功能?

例如:

# import asyncio
# @asyncio.coroutine
def gen():
    value = yield("Started")
    print(value)

a = gen()
a.send(None)
a.send("Done")

现在如果我取消注释前两行并使用asyncio.coroutine装饰器,我仍然会得到相同的输出。

我的意思是这已经是coroutine - 一个可以暂停并通过参数传入的函数。为什么我需要用另一个coroutine装饰它,即asyncio.coroutine

1 个答案:

答案 0 :(得分:4)

了解generatorsasyncio coroutines - 是不同的事情非常重要。协同程序是使用生成器实现的,但(理论上)可以在没有它们的情况下实现。 Genarators - 是关于协程的实现的一部分。

由于asyncio协同程序是使用生成器实现的,因此有时可以使用生成器作为协同程序而不会出现错误:

import asyncio


def main():
    yield from asyncio.sleep(1)
    print('done')


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

<强>结果:

done

但它并不适用于各种协程:

import asyncio


def main():
    # yield from asyncio.sleep(1)
    print('done')


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

<强>结果:

TypeError: An asyncio.Future, a coroutine or an awaitable is required

这就是为什么(除了few other事物)asyncio.coroutine装饰者使用:

import asyncio


@asyncio.coroutine
def main():
    # yield from asyncio.sleep(1)
    print('done')


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

<强>结果:

done

但正如所有人已经指出的那样,今天实际上并不重要:因为Python 3.5装饰器和yield from已经被关键字async defawait所取代,这不仅更好,而且有帮助以更好的方式从协议实现细节中分离协同程序。

import asyncio


async def main():
    # await asyncio.sleep(1)
    print('done')


loop = asyncio.get_event_loop()
loop.run_until_complete(main())