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

例如:

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

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

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

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

最佳答案

重要的是要了解generatorsasyncio coroutines-是不同的东西。协程是使用生成器实现的,但是(理论上)可以不使用生成器来实现。生成器-是有关协程的实现的一部分。

由于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

这就是asyncio.coroutine装饰器使用yield from的原因(除了few other之外):
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装饰器和async def已被关键字await和ojit_code取代,不仅更好,而且有助于以更好的方式将协程与实现细节分开。
import asyncio


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


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

10-06 05:21