如何在 python 3.8 的异步编程中使用“yield”语句?

Ada*_*mer 4 python python-asyncio

在python的asyncio异步编程(3.7或以下版本)中,如果我想手动让协程将其控制权交还给主事件循环,我可以使用以下代码:

@asyncio.coroutine
def switch():
    yield
    return

async def task():
    # ...do something
    # ...
    await switch() # then this coroutine will be suspended and other will be triggered
    # ...
    # ... do something else when it's triggered again.
Run Code Online (Sandbox Code Playgroud)

然而,在 python3.8 中,“@coroutine”装饰器已被弃用。除此之外,我无法在“async def”中使用yield(因为它将定义异步生成器而不是协程)。那么我怎样才能实现同样的功能呢?

Mis*_*agi 6

TLDR:不要使用显式yield切换协程。对于asyncio,请asyncio.sleep(0)改为使用。

\n
\n

实际上,所有事件循环都将各自的sleep持续时间视为 0,表示“让其他协程运行”。\n对于asyncio,使用asyncio.sleep(0)让其他协程运行。

\n
async def task():\n    # ...do something\n    # ...\n    await asyncio.sleep(0) # then this coroutine will be suspended and other will be triggered\n    # ...\n    # ... do something else when it\'s triggered again.\n
Run Code Online (Sandbox Code Playgroud)\n
\n

睡觉( asyncio)

\n
\n
\n

sleep()始终挂起当前任务,允许其他任务运行。

\n
\n
\n

检查点( trio)

\n
\n
\n

\xe2\x80\xa6 \xe2\x80\x99 很有用,知道这await trio.sleep(0)是执行检查点而不执行任何其他操作的惯用方法 \xe2\x80\xa6

\n
\n
\n

时间curio

\n
\n
\n

休眠指定的秒数。如果秒数为 0,则执行切换到下一个就绪任务(如果有)。

\n
\n
\n

如果由于某种原因yield需要显式事件循环,请创建一个自定义类并yield使用其__await__特殊方法。

\n
class Switch:\n    """Switch coroutines by yielding to the event loop"""\n    def __await__(self):\n        yield\n
Run Code Online (Sandbox Code Playgroud)\n

请注意,这会None向事件循环发送一个裸数据。事件循环是否以及如何处理此信号取决于所使用的异步库。

\n