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

时间:2019-01-08 17:05:04

标签: python-3.x python-asyncio coroutine

在python 3.6中练习编写coroutines, 注意到两者都在:

from asyncio import coroutine

并在:

from types import coroutine

有2个装饰器,乍看之下它们是相同的。

首先阅读文档(来自asyncio

  

标记协程的装饰器

第二个(来自types):

  

将常规生成器函数转换为协程。

让我更加困惑。 我知道我可以在python3.6中使用async yield from,所以我迷失了对这两者之间的区别的真正了解。

请协助

2 个答案:

答案 0 :(得分:1)

随着async def语法的出现,很少使用两个修饰符,并且asyncio.coroutine正式是deprecated

types.coroutine装饰器仍然可用作从生成器创建协程的低级工具。在为自定义事件循环实现设计基元时,这种事情很有用。借助@types.coroutine,您可以使用准系统生成器创建协程,该准系统生成器的yield会直接在事件循环中产生您选择的值。

例如,sleep协程实现可能看起来像这样:

@types.coroutine
def sleep(delay):
    deadline = time.time() + delay
    yield 'sleep_until', deadline

这将创建一个与async def创建的协程类似的协程,但是具有与兼容事件循环进行通信的神奇能力,该事件循环可能包含以下代码:

def run(self):
    while self._to_run:
        coro = self._to_run.popleft()
        try:
            cmd, arg = coro.send(None)
        except StopIteration:
            continue
        if cmd == 'sleep_until':
            self._to_wake[arg] = coro
    time.sleep(min(self._to_wake) - time.time())
    self._to_run.extend(coro for t, coro in self._to_wake.items()
                        if t <= time.time())

有关更多详细信息,请参阅David Beazley的this lecture,其中在现场观众面前构建了功能齐全的事件循环。 (不要因使用yield from而推迟-较新的async def的工作方式完全相同。)

答案 1 :(得分:0)

如果您使用的是Python 3.5+,则无需考虑。

创建协程的现代方法是使用async def进行定义。如果您使用的是最新的Python版本,请遵循相关的documentation


如果您对回顾感兴趣:

asyncio.coroutine装饰器是一种创建Python 3.5之前使用的协程人员的旧方法。

types.coroutine只是an utility function,主要在Python内部使用。正如jonrsharpe所指出的,asyncio.coroutine在其实现中使用types.coroutine。碰巧是公开的,这很奇怪,我从未见过有人使用过它。您可能还不应该:)