【问题标题】:What is the differnce between asyncio.coroutime and types.coroutine decorators? [duplicate]asyncio.coroutine 和 types.coroutine 装饰器有什么区别? [复制]
【发布时间】:2019-06-03 10:11:00
【问题描述】:

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

from asyncio import coroutine

在:

from types import coroutine

乍一看,有两个装饰器是一样的。

阅读first(from asyncio)的文档

装饰器来标记协程

第二个(来自types):

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

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

请帮忙

【问题讨论】:

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


【解决方案1】:

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

创建协程的现代方式是用async def 定义它。如果您使用的是最新的 Python 版本,请关注相关的documentation


如果您对回顾感兴趣:

asyncio.coroutine 装饰器是在 Python 3.5 之前创建协程的老方法。

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

【讨论】:

    【解决方案2】:

    随着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 的工作方式完全相同。)

    【讨论】:

      猜你喜欢
      • 2023-03-21
      • 2012-01-09
      • 2020-02-21
      • 2019-11-24
      • 2016-09-16
      • 2018-04-17
      • 1970-01-01
      • 2011-02-04
      • 2018-07-19
      相关资源
      最近更新 更多