Как можно перехватывать несколько разных исключений в одном блоке `except`?

Можно перечислить исключения в кортеже в блоке except:

try:
  # Код, который может вызвать исключения
  pass
except (TypeError, ValueError, IndexError) as e:
  # Обработка TypeError, ValueError или IndexError
  print(f"Произошла ошибка: {type(e).__name__}")
  
Или, используя вертикальную черту начиная с Python 3.11:

try:
  # Код, который может вызвать исключения
  pass
except TypeError | ValueError | IndexError as e:
  # Обработка TypeError, ValueError или IndexError
  print(f"Произошла ошибка: {type(e).__name__}")
  

В Python можно перехватывать несколько разных исключений в одном блоке except несколькими способами:

  1. Указание исключений кортежем:

    Самый распространенный и рекомендуемый способ - перечислить исключения в кортеже после ключевого слова except.

    try:
        # Код, который может вызвать исключения
        num = int(input("Введите число: "))
        result = 10 / num
        print(f"Результат: {result}")
    except (ValueError, ZeroDivisionError) as e:
        print(f"Произошла ошибка: {e}")
    except Exception as e: # Перехватываем все остальные исключения
        print(f"Непредвиденная ошибка: {e}")
    else:
      print("Код выполнился без ошибок.")
    finally:
      print("Этот код выполнится всегда, независимо от наличия исключений.")
    

    В этом примере ValueError (если введен некорректный формат числа) и ZeroDivisionError (если число равно 0) будут перехвачены одним блоком except. Переменная e, указанная после as, будет содержать экземпляр произошедшего исключения.

  2. Иерархия исключений:

    Можно перехватывать базовый класс исключения, который охватывает несколько производных классов. Например, ArithmeticError является базовым классом для ZeroDivisionError и OverflowError.

    try:
        # Код, который может вызвать исключения
        num = int(input("Введите число: "))
        result = 10 / num
        print(f"Результат: {result}")
    except ArithmeticError as e:
        print(f"Арифметическая ошибка: {e}") # Перехватит ZeroDivisionError и OverflowError
    except ValueError as e:
        print(f"Ошибка ввода: {e}")
    except Exception as e: # Перехватываем все остальные исключения
        print(f"Непредвиденная ошибка: {e}")
    else:
      print("Код выполнился без ошибок.")
    finally:
      print("Этот код выполнится всегда, независимо от наличия исключений.")
    

    В этом случае, если возникнет ZeroDivisionError или OverflowError, будет выполнен блок except ArithmeticError.

  3. Последовательные блоки except с общей логикой:

    Хотя это и не перехват нескольких исключений в одном блоке except в строгом смысле, можно написать несколько блоков except подряд, выполняющих одинаковые действия.

    try:
        # Код, который может вызвать исключения
        num = int(input("Введите число: "))
        result = 10 / num
        print(f"Результат: {result}")
    except ValueError as e:
        print(f"Ошибка: {e}")
        # Общая логика обработки
    except ZeroDivisionError as e:
        print(f"Ошибка: {e}")
        # Общая логика обработки (дублируется)
    except Exception as e: # Перехватываем все остальные исключения
        print(f"Непредвиденная ошибка: {e}")
    else:
      print("Код выполнился без ошибок.")
    finally:
      print("Этот код выполнится всегда, независимо от наличия исключений.")
    

    Обратите внимание, что в этом случае код обработки ошибки дублируется. Если требуется выполнять одинаковые действия для нескольких исключений, лучше использовать первый способ (кортеж исключений).

Важно помнить:

  • Порядок блоков except имеет значение. Исключения перехватываются в том порядке, в котором они указаны. Блок except Exception должен быть последним, чтобы не перехватить все исключения, предназначенные для более специфичных обработчиков.
  • Рекомендуется перехватывать только те исключения, которые вы знаете, как обработать. Перехват всех исключений (например, except Exception без необходимости) может скрыть важные ошибки и затруднить отладку.
  • Использование блоков else и finally помогает писать более надежный код. Блок else выполняется, если в блоке try не было исключений, а блок finally выполняется всегда, независимо от того, было ли исключение или нет.
0