Сообщить об ошибке.

Три механизма запуска сопрограммы (coroutines) модуля asyncio.

Сопрограммы или coroutines, объявленные с синтаксисом async/await, являются предпочтительным способом написания приложений, с использованием модуля asyncio.

Например, следующий фрагмент кода (требуется Python 3.7+) печатает "hello", ждет 1 секунду, а затем печатает "world":

>>> import asyncio

>>> async def main():
...     print('hello')
...     await asyncio.sleep(1)
...     print('world')

>>> asyncio.run(main())
# hello
# world

Обратите внимание, что простой вызов сопрограммы main() не приведет к ее выполнению:

>>> main()
# <coroutine object main at 0x1053bb7c8>

Три основных механизма фактического запуска сопрограммы.

  1. Основной цикл событий (точку входа верхнего уровня) можно запустить при помощи функция asyncio.run(). Смотрите пример выше.

  2. Запуск сопрограмм, которые должны или могут ждать каких-то результатов (например, ответа сервера с результатами запроса) запускаются оператором await.

    Следующий фрагмент кода напечатает "hello" после ожидания в течение 1 секунды, а затем напечатает "world" после ожидания еще 2-х секунд:

    import asyncio, time
    
    async def say_after(delay, what):
        """Асинхронная функция (сопрограмма)"""
        await asyncio.sleep(delay)
        print(what)
    
    async def main():
        """Точка входа в асинхронную программу"""
        print(f"started at {time.strftime('%X')}")
    
        # запуск сопрограммы `say_after()` происходит при  
        # помощи оператора `await`, т. к. в самой сопрограмме  
        # есть объект ожидания - неблокирующая функция 
        # `asyncio.sleep()`, которая эмитирует ожидание ответа сервера
        await say_after(1, 'hello')
        await say_after(2, 'world')
    
        print(f"finished at {time.strftime('%X')}")
    
    # запуск основного цикла событий 
    asyncio.run(main())
    
    # started at 12:23:15
    # hello
    # world
    # finished at 12:23:18
    
  3. Третий вариант: запуск сопрограмм можно осуществлять через создание и планирование задач при помощи функции asyncio.create_task(). Объекты задач Task также являются объектами ожидания результата, т.к. планируют запуск сопрограмм в будущем, как только это станет возможным. Следовательно задачи, то же запускаем оператором await

    Изменим предыдущий пример и одновременно запустим две сопрограммы say_after():

    import asyncio, time
    
    async def say_after(delay, what):
        """Асинхронная функция (сопрограмма)"""
        await asyncio.sleep(delay)
        print(what)
    
    async def main():
        """Точка входа в асинхронную программу"""
    
        # создаем задачи `task1` и `task2`
        task1 = asyncio.create_task(say_after(1, 'hello'))
        task2 = asyncio.create_task(say_after(2, 'world'))
    
        print(f"started at {time.strftime('%X')}")
    
        # Ждем, пока обе задачи будут выполнены 
        # (должно занять около 2 секунд.)
        await task1
        await task2
        print(f"finished at {time.strftime('%X')}")
    
     asyncio.run(main())
    
    # started at 12:29:25
    # hello
    # world
    # finished at 12:29:27
    

Обратите внимание, что фрагмент кода выполняется на 1 секунду быстрее, чем раньше.