Функция asyncio.gather() в Python с примерами использования

В этом руководстве вы узнаете, как использовать функцию asyncio.gather() для выполнения нескольких асинхронных операций в Python.

Содержание

Что такое функция asyncio.gather() в Python?

Иногда вам может потребоваться запустить несколько асинхронных операций и получить результаты после их завершения. Для этого вы можете использовать функцию asyncio.gather():

gather(*aws, return_exceptions=False) -> Future[tuple[()]]

Функция asyncio.gather() имеет два параметра:

  • aws — это последовательность ожидаемых объектов. Если какой-либо объект в aws является сопрограммой, функция asyncio.gather() автоматически запланирует его как задачу.
  • return_Exceptions — по умолчанию имеет значение False. Если исключение возникает в ожидаемом объекте, оно немедленно распространяется на задачу, ожидающую asyncio.gather(). Другие ожидаемые события продолжат действовать и не будут отменены.

Метод asyncio.gather() возвращает результаты ожидаемых объектов в виде кортежа в том же порядке, в котором вы передаете ожидаемые объекты в функцию. Если return_Exceptions имеет значение True. asyncio.gather() добавит исключение, если таковое имеется, к результату и не будет передавать его вызывающему объекту.

Примеры использования asyncio.gather() в Python

Давайте рассмотрим несколько примеров использования функции asyncio.gather().

1)Запуск нескольких асинхронных операций с asyncio.gather()

В данном примере метод asyncio.gather() используется для запуска двух асинхронных операций и отображает результаты:

import asyncio


async def call_api(message, result, delay=3):
    print(message)
    await asyncio.sleep(delay)
    return result


async def main():
    a, b = await asyncio.gather(
        call_api('Calling API 1 ...', 1),
        call_api('Calling API 2 ...', 2)
    )
    print(a, b)


asyncio.run(main())

Выход:

Calling API 1 ...
Calling API 2 ...
100 200

Как это работает.

  • Сначала определим сопрограмму call_api(), которая имитирует асинхронную операцию. Call_api() отображает сообщение, задерживается на несколько секунд и возвращает результат:
async def call_api(message, result, delay=3):
    print(message)
    await asyncio.sleep(delay)
    return result

Затем используем функцию asyncio.gather() для запуска двух call_api():

async def main():
    a, b = await asyncio.gather(
        call_api('Calling API 1 ...', 100, 1),
        call_api('Calling API 2 ...', 200, 2)
    )
    print(a, b)

Первая сопрограмма занимает 1 секунду и возвращает 100, а вторая сопрограмма занимает 2 секунды и возвращает 100. Через 2 секунды сбор возвращает результат в виде кортежа, содержащего результаты первой и второй сопрограмм.

Обратите внимание, что a равно 100, а b равно 200, что является результатом соответствующей сопрограммы, которую мы передаем в функцию asyncio.gather().

2) Пример запуска нескольких асинхронных операций с исключениями

В следующем примере показано, как использовать функцию asyncio.gather() для выполнения нескольких асинхронных операций, когда операция вызывает исключение:

import asyncio


class APIError(Exception):
    def __init__(self, message):
        self._message = message

    def __str__(self):
        return self._message


async def call_api_failed():
    await asyncio.sleep(3)
    raise APIError('API failed')


async def call_api(message, result, delay=3):
    print(message)
    await asyncio.sleep(delay)
    return result


async def main():
    a, b, c = await asyncio.gather(
        call_api('Calling API 1 ...', 100, 1),
        call_api('Calling API 2 ...', 200, 2),
        call_api_failed()
    )
    print(a, b, c)


asyncio.run(main())

Как это работает.

  • Сначала определим новый класс исключений APIError, который наследуется от класса Exception:
class APIError(Exception):
    def __init__(self, message):
        self._message = message

    def __str__(self):
        return self._message
  • Во-вторых, определим сопрограмму call_api_failed(), которая задерживает 1 секунду и вызывает исключение APIError:
async def call_api_failed():
    await asyncio.sleep(3)
    raise APIError('API failed')
  • В-третьих, передадим три сопрограммы в функцию asyncio.gather(). Через одну секунду call_api_failed() вызывает исключение, которое немедленно передается в функцию asyncio.gather():
async def main():
    a, b, c = await asyncio.gather(
        call_api('Calling API 1 ...', 100, 1),
        call_api('Calling API 2 ...', 200, 2),
        call_api_failed()
    )
    print(a, b, c)

Если вы запустите программу, вы увидите исключение APIError.

3) Использование asyncio.gather() для возврата исключения в результате

Чтобы получить исключение в результате, вы устанавливаете для параметра return_Exceptions значение True следующим образом:

import asyncio


class APIError(Exception):
    def __init__(self, message):
        self._message = message

    def __str__(self):
        return self._message


async def call_api(message, result, delay=3):
    print(message)
    await asyncio.sleep(delay)
    return result


async def call_api_failed():
    await asyncio.sleep(1)
    raise APIError('API failed')


async def main():
    a, b, c = await asyncio.gather(
        call_api('Calling API 1 ...', 100, 1),
        call_api('Calling API 2 ...', 200, 2),
        call_api_failed(),
        return_exceptions=True
    )
    print(a, b, c)


asyncio.run(main())

Выход:

Calling API 1 ...
Calling API 2 ...
100 200 API failed

В этом примере, поскольку для return_Exceptions установлено значение True, asyncio.gather() возвращает исключение как часть результата.

Похожие посты
Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *