Как я могу использовать оператор yield в python 3.8 асинхронном программировании? - PullRequest
1 голос
/ 09 марта 2020

В асинхронном программировании python (версия 3.7 или ниже), если я хочу вручную разрешить сопрограмме вернуть контроль над главным событием l oop, я могу использовать этот код:

@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.

Однако в python3 .8 декоратор "@coroutine" устарел. И кроме того, я не мог использовать yield в 'asyn c def' (поскольку он будет определять генератор asyn c, но не сопрограмму). Так, как я мог достигнуть той же самой функции?

1 Ответ

2 голосов
/ 09 марта 2020

TLDR: не используйте явный yield для переключения сопрограмм. Для asyncio используйте взамен asyncio.sleep(0).


Практически все циклы событий считают свои соответствующие sleep с длительностью 0, что означает «запускать другие сопрограммы». Для asyncio используйте asyncio.sleep(0) для запуска других сопрограмм.

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

Спящий (asyncio)

sleep() всегда приостанавливается текущая задача, позволяющая запускать другие задачи.

Контрольные точки (trio)

… полезно знать, что await trio.sleep(0) является идиоматическим c способом выполнить контрольную точку, ничего не делая…

Время (curio)

Сон в течение указанного количества секунд. Если количество секунд равно 0, выполнение переключается на следующую готовую задачу (если есть).


Если по какой-то причине требуется явное yield для события l oop , создайте пользовательский класс и yield в его специальном методе __await__.

class Switch:
    """Switch coroutines by yielding to the event loop"""
    async def __await__(self):
        yield

Обратите внимание, что это отправляет пустое значение None событию l oop. Способ обработки этого сигнала событием l oop зависит от используемой библиотеки asyn c.

...