В этом руководстве вы узнаете, как использовать функцию 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() возвращает исключение как часть результата.
