Как можно запустить асинхронную функцию в Python?

Для запуска асинхронной функции в Python необходимо использовать:
  • asyncio.run(async_function()): Самый простой способ для запуска в синхронном коде. Запускает event loop и закрывает его по завершении.
  • await async_function(): Внутри другой асинхронной функции или корутины.
  • asyncio.create_task(async_function()): Создает задачу (task), которая будет запущена параллельно в event loop. Необходимо дождаться завершения задачи (например, через await task) или использовать asyncio.gather.

В Python асинхронную функцию можно запустить несколькими способами, но все они так или иначе требуют использования event loop (цикла событий).

Основные способы запуска асинхронных функций:

  1. Использование asyncio.run() (рекомендуемый способ для простых случаев):

    Это самый простой и современный способ запустить асинхронную функцию. asyncio.run() автоматически создает event loop, запускает переданную корутину, дожидается её завершения и затем закрывает event loop. Этот метод идеально подходит для запуска одной асинхронной функции из синхронного кода, например, в начале программы.

    import asyncio
    
    async def my_async_function():
        print("Hello from async function!")
        await asyncio.sleep(1)  # Имитация асинхронной работы
        print("Async function finished!")
    
    if __name__ == "__main__":
        asyncio.run(my_async_function())
        print("Program finished!")
    
  2. Использование asyncio.create_task() и asyncio.gather():

    asyncio.create_task() позволяет запланировать выполнение корутины в event loop, не дожидаясь её завершения сразу. Это полезно, когда нужно запустить несколько корутин параллельно. asyncio.gather() позволяет собрать результаты выполнения нескольких корутин.

    import asyncio
    
    async def my_async_function(name):
        print(f"Hello from async function {name}!")
        await asyncio.sleep(1)
        print(f"Async function {name} finished!")
        return f"Result from {name}"
    
    async def main():
        task1 = asyncio.create_task(my_async_function("Task 1"))
        task2 = asyncio.create_task(my_async_function("Task 2"))
    
        results = await asyncio.gather(task1, task2)
        print(f"Results: {results}")
    
    if __name__ == "__main__":
        asyncio.run(main())
    
  3. Получение event loop напрямую (для более сложного управления):

    Можно получить текущий event loop с помощью asyncio.get_event_loop() и использовать его методы, такие как loop.run_until_complete() или loop.run_forever(). Этот способ дает больше контроля, но и требует большей ответственности за управление event loop.

    import asyncio
    
    async def my_async_function():
        print("Hello from async function!")
        await asyncio.sleep(1)
        print("Async function finished!")
    
    if __name__ == "__main__":
        loop = asyncio.get_event_loop()
        try:
            loop.run_until_complete(my_async_function())
        finally:
            loop.close()
    

    Важно: Закрывайте event loop после использования, чтобы избежать утечек ресурсов. В примере выше это делается в блоке finally.

  4. Использование await внутри другой async функции:

    Основной способ запуска асинхронной функции - это вызвать ее внутри другой асинхронной функции с использованием ключевого слова await.

    import asyncio
    
    async def first_async_function():
        print("First function started")
        await asyncio.sleep(1)
        print("First function finished")
        return "Result from first function"
    
    async def second_async_function():
        print("Second function started")
        result = await first_async_function()
        print(f"Second function received result: {result}")
        await asyncio.sleep(1)
        print("Second function finished")
    
    
    if __name__ == "__main__":
        asyncio.run(second_async_function())
    

Ключевые моменты:

  • Асинхронные функции должны быть объявлены с помощью ключевого слова async.
  • Внутри асинхронной функции можно использовать await для приостановки выполнения до завершения другой асинхронной операции.
  • Для запуска асинхронных функций необходимо использовать event loop.

Выбор способа запуска зависит от конкретной задачи. Для простых случаев, как правило, достаточно asyncio.run(). Для более сложных сценариев с параллельным выполнением задач лучше использовать asyncio.create_task() и asyncio.gather(). Прямое управление event loop требуется только в исключительных случаях.

0