В Python 3.11 были добавлены новые классы исключений
BaseExceptionGroup и ExceptionGroup. Эти классы решают проблему одновременной обработки нескольких исключений, которые могут возникать в сложных ситуациях, таких как асинхронное программирование, многопоточность или обработка нескольких связанных ошибок. Давайте разберем, зачем они нужны, как их использовать и какие преимущества они дают.🚩Зачем нужны `BaseExceptionGroup` и `ExceptionGroup`?
Ранее в Python было возможно выбросить только одно исключение за раз, и обработка нескольких исключений одновременно требовала сложного и неочевидного кода. Например:
При работе с асинхронными функциями или потоками может возникнуть сразу несколько ошибок, и их нужно корректно обработать.
В больших приложениях или библиотеках (например, при работе с
asyncio) может быть необходимость передать сразу несколько исключений, которые произошли в разных местах, как единый объект.BaseExceptionGroup и его подкласс ExceptionGroup позволяют группировать несколько исключений и выбрасывать их вместе в виде одного объекта. Это делает код более читаемым, упрощает обработку и исключает необходимость ручной агрегации ошибок.🚩Разница между `BaseExceptionGroup` и `ExceptionGroup`
BaseExceptionGroup - это базовый класс для группировки исключений. Он наследуется от BaseException и, как правило, не используется напрямую.ExceptionGroup - это подкласс, который наследуется от Exception. Этот класс используется для обработки групп исключений, которые возникают при обычных ошибках в коде (не фатальных).🚩Как они работают?
Классы исключений
BaseExceptionGroup и ExceptionGroup позволяют создать "группу исключений", которая содержит несколько отдельных исключений. Это полезно, когда вам нужно:Указать несколько ошибок одновременно.
Позволить обработчику исключений работать с каждым из них.
def task_1():
raise ValueError("Ошибка в задаче 1")
def task_2():
raise TypeError("Ошибка в задаче 2")
try:
# Создаем группу исключений
raise ExceptionGroup(
"Ошибки в задачах",
[ValueError("Ошибка в задаче 1"), TypeError("Ошибка в задаче 2")]
)
except ExceptionGroup as eg:
for exc in eg.exceptions:
print(f"Обнаружено исключение: {exc}")
Результат
Обнаружено исключение: Ошибка в задаче 1
Обнаружено исключение: Ошибка в задаче 2
🚩Обработка групп исключений
При обработке
ExceptionGroup можно использовать механизм фильтрации с помощью конструкции except*. Это нововведение в Python 3.11 позволяет обрабатывать разные типы исключений внутри группы по-разному.try:
raise ExceptionGroup(
"Ошибки в задачах",
[ValueError("Ошибка 1"), TypeError("Ошибка 2"), ValueError("Ошибка 3")]
)
except* ValueError as ve:
print("Обрабатываем ValueError:", ve)
except* TypeError as te:
print("Обрабатываем TypeError:", te)
Результат
Обрабатываем ValueError: Ошибка 1
Обрабатываем ValueError: Ошибка 3
Обрабатываем TypeError: Ошибка 2
🚩Преимущества использования
➕Работа с несколькими исключениями одновременно.
Вы можете объединить связанные ошибки и передать их в одном объекте.
➕Четкое разграничение типов исключений.
Использование
except* позволяет обработать каждое исключение из группы отдельно, не теряя гибкости.➕Удобство при асинхронном программировании.
В асинхронных задачах (
asyncio) часто возникает несколько ошибок одновременно, и их можно группировать для дальнейшей обработки.➕Упрощение сложной логики.
Код становится проще и понятнее, так как не нужно вручную собирать и разбирать исключения.
🚩Когда использовать?
Когда вы работаете с несколькими задачами, которые могут порождать ошибки одновременно (например, асинхронный код).
Когда вы хотите сообщить о нескольких связанных ошибках, не выбрасывая каждую из них отдельно.
Когда требуется раздельная обработка разных типов ошибок.
Ставь 👍 и забирай 📚 Базу знаний