Функция asyncio.gather() в Python с примерами использования
В этом руководстве вы узнаете, как использовать функцию asyncio.gather() для выполнения нескольких асинхронных операций в Python.
- Что такое функция asyncio.gather() в Python?
- Примеры использования asyncio.gather() в Python
- 1)Запуск нескольких асинхронных операций с asyncio.gather()
- 2) Пример запуска нескольких асинхронных операций с исключениями
- 3) Использование asyncio.gather() для возврата исключения в результате
Что такое функция 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() возвращает исключение как часть результата.