@ types.coroutine和@asyncio.coroutine装饰器之间有什么区别?

com*_*ex3 18 python asynchronous python-3.5

文件说:

@ asyncio.coroutine

装饰器标记基于生成器的协同程序.这使得生成器使用yield来调用异步def协同程序,并且还允许异步def协同程序调用生成器,例如使用await表达式.

_

@ types.coroutine(gen_func)

此函数将生成器函数转换为协程函数,该函数返回基于生成器的协同程序.基于生成器的协程仍然是生成器迭代器,但也被认为是协程对象并且是等待的.但是,它可能不一定实现该__await__() 方法.

所以似乎目的是相同的 - 将生成器标记为协程(async defPython3.5及更高版本中的某些功能).

当需要使用asyncio.coroutine时需要使用types.coroutine,有什么不同之处?

Дми*_*нко 9

区别在于您是否有 yield 语句。这是代码:

from types import coroutine as t_coroutine
from asyncio import coroutine as a_coroutine, ensure_future, sleep, get_event_loop


@a_coroutine
def a_sleep():
    print("doing something in async")
    yield 1


@t_coroutine
def t_sleep():
    print("doing something in types")
    yield 1


async def start():
    sleep_a = a_sleep()
    sleep_t = t_sleep()
    print("Going down!")


loop = get_event_loop()
loop.run_until_complete(start())
Run Code Online (Sandbox Code Playgroud)

在这个例子中,一切似乎都一样——这是来自 pycharm 的调试信息(我们站在“Going down!”行上)。控制台中尚未打印任何内容,因此功能尚未启动。

PyCharm 调试

但是如果我们删除yield,该types版本将立即启动功能!

from types import coroutine as t_coroutine
from asyncio import coroutine as a_coroutine, ensure_future, sleep, get_event_loop


@a_coroutine
def a_sleep():
    print("doing something in async")


@t_coroutine
def t_sleep():
    print("doing something in types")


async def start():
    sleep_a = a_sleep()
    sleep_t = t_sleep()
    print("Going down!")


loop = get_event_loop()
loop.run_until_complete(start())
Run Code Online (Sandbox Code Playgroud)

现在我们doing something in types在控制台打印了。这是调试信息:

新的调试信息

如您所见,它在 call 之后立即开始,如果没有结果并返回 None。


至于用法,您应该asyncio始终使用版本。如果您需要像火一样运行它而忘记(立即运行并稍后获得结果) - 使用ensure_future函数。