为什么我们需要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
装饰它? 最佳答案
重要的是要了解generators和asyncio
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())