Как проверить, является ли исключение определенного типа в Python

PythonPythonBeginner
Практиковаться сейчас

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

В этом практическом занятии (лабораторной работе) вы научитесь проверять, является ли исключение определенного типа в Python, что является важным навыком для эффективной обработки ошибок. Лабораторная работа сосредоточена на понимании иерархии исключений и использовании этой информации для идентификации конкретных типов исключений.

В рамках лабораторной работы вы исследуете иерархию исключений Python, начиная от базового класса BaseException и его подклассов, таких как Exception. Вы создадите скрипт на Python exception_hierarchy.py, который выведет на экран иерархию исключений, позволяя вам визуализировать отношения между различными классами исключений. Затем полученное понимание будет применено в последующих шагах для проверки типов исключений с использованием функции isinstance() и прямого сравнения классов.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL python(("Python")) -.-> python/ErrorandExceptionHandlingGroup(["Error and Exception Handling"]) python/ErrorandExceptionHandlingGroup -.-> python/catching_exceptions("Catching Exceptions") python/ErrorandExceptionHandlingGroup -.-> python/raising_exceptions("Raising Exceptions") python/ErrorandExceptionHandlingGroup -.-> python/custom_exceptions("Custom Exceptions") subgraph Lab Skills python/catching_exceptions -.-> lab-559609{{"Как проверить, является ли исключение определенного типа в Python"}} python/raising_exceptions -.-> lab-559609{{"Как проверить, является ли исключение определенного типа в Python"}} python/custom_exceptions -.-> lab-559609{{"Как проверить, является ли исключение определенного типа в Python"}} end

Понимание иерархии исключений

В этом шаге вы узнаете о иерархии исключений в Python. Понимание этой иерархии является ключевым моментом для эффективной обработки ошибок. Исключения в Python организованы в древовидной структуре, где вверху находится базовый класс, а от него наследуются более конкретные классы исключений.

Базовым классом для всех исключений является BaseException. Прямо от BaseException наследуются классы Exception, GeneratorExit, KeyboardInterrupt и SystemExit. Класс Exception является суперклассом для большинства встроенных исключений, которые указывают на ошибки, с которыми может столкнуться ваша программа.

Давайте создадим скрипт на Python для исследования этой иерархии.

  1. Откройте редактор VS Code.

  2. Создайте новый файл с именем exception_hierarchy.py в директории ~/project.

    ~/project/exception_hierarchy.py
  3. Добавьте следующий код в файл exception_hierarchy.py:

    def print_exception_hierarchy(exception_class, indent=0):
        """Prints the exception hierarchy starting from a given exception class."""
        print('  ' * indent + str(exception_class))
        for subclass in exception_class.__subclasses__():
            print_exception_hierarchy(subclass, indent + 1)
    
    print("Exception Hierarchy:")
    print_exception_hierarchy(Exception)

    Этот скрипт определяет рекурсивную функцию print_exception_hierarchy, которая выводит на экран иерархию исключений, начиная от класса Exception.

  4. Запустите скрипт, используя следующую команду в терминале:

    python exception_hierarchy.py

    Это выведет на терминал древовидную структуру иерархии исключений.

    Пример вывода:

    Exception Hierarchy:
    <class 'Exception'>
      <class 'ArithmeticError'>
        <class 'FloatingPointError'>
        <class 'OverflowError'>
        <class 'ZeroDivisionError'>
          <class 'decimal.DivisionByZero'>
      <class 'AssertionError'>
      <class 'AttributeError'>
      <class 'BufferError'>
      <class 'EOFError'>
      <class 'ImportError'>
        <class 'ModuleNotFoundError'>
        <class 'ZipImportError'>
      <class 'LookupError'>
        <class 'IndexError'>
        <class 'KeyError'>
          <class 'tracemalloc.DomainKey'>
      <class 'MemoryError'>
      <class 'NameError'>
        <class 'UnboundLocalError'>
      <class 'OSError'>
        <class 'BlockingIOError'>
        <class 'ChildProcessError'>
        <class 'ConnectionError'>
          <class 'BrokenPipeError'>
          <class 'ConnectionAbortedError'>
          <class 'ConnectionRefusedError'>
          <class 'ConnectionResetError'>
        <class 'FileExistsError'>
        <class 'FileNotFoundError'>
        <class 'InterruptedError'>
          <class 'InterruptedSystemCall'>
        <class 'IsADirectoryError'>
        <class 'NotADirectoryError'>
        <class 'PermissionError'>
        <class 'ProcessLookupError'>
        <class 'TimeoutError'>
        <class 'UnsupportedOperation'>
        <class 'itertools.Incomplete'>
        <class 'signal.ItimerError'>
      <class 'ReferenceError'>
      <class 'RuntimeError'>
        <class 'NotImplementedError'>
          <class 'asyncio.exceptions.IncompleteReadError'>
          <class 'zlib.error'>
        <class '_frozen_importlib._DeadlockError'>
        <class 'RecursionError'>
      <class 'StopAsyncIteration'>
      <class 'StopIteration'>
      <class 'SyntaxError'>
        <class 'IndentationError'>
          <class 'TabError'>
      <class 'SystemError'>
      <class 'TypeError'>
      <class 'ValueError'>
        <class 'UnicodeError'>
          <class 'UnicodeDecodeError'>
          <class 'UnicodeEncodeError'>
          <class 'UnicodeTranslateError'>
      <class 'Warning'>
        <class 'BytesWarning'>
        <class 'DeprecationWarning'>
        <class 'EncodingWarning'>
        <class 'FutureWarning'>
        <class 'ImportWarning'>
        <class 'PendingDeprecationWarning'>
        <class 'ResourceWarning'>
        <class 'RuntimeWarning'>
        <class 'SyntaxWarning'>
        <class 'UnicodeWarning'>
        <class 'UserWarning'>

    Этот вывод показывает иерархию исключений, где Exception является базовым классом, а различные подклассы представляют конкретные типы ошибок. Понимание этой иерархии помогает вам перехватывать исключения на соответствующем уровне детализации. Например, вы можете перехватить конкретное исключение, такое как ZeroDivisionError, или более общее исключение, как ArithmeticError (который является родителем ZeroDivisionError).

Использование функции isinstance() для обработки исключений

В этом шаге вы научитесь использовать функцию isinstance() для проверки, является ли исключение экземпляром определенного класса или кортежа классов. Это полезно для гибкой обработки различных типов исключений.

Функция isinstance() принимает два аргумента: объект и classinfo (информацию о классе). Она возвращает True, если объект является экземпляром classinfo или его подкласса. В противном случае возвращается False.

Давайте создадим скрипт на Python, чтобы продемонстрировать использование isinstance() с исключениями.

  1. Откройте редактор VS Code.

  2. Создайте новый файл с именем isinstance_exception.py в директории ~/project.

    ~/project/isinstance_exception.py
  3. Добавьте следующий код в файл isinstance_exception.py:

    try:
        result = 10 / 0
    except Exception as e:
        if isinstance(e, ZeroDivisionError):
            print("Caught a ZeroDivisionError!")
        elif isinstance(e, ArithmeticError):
            print("Caught an ArithmeticError!")
        else:
            print("Caught some other exception!")
    
    print("Program continues...")

    В этом скрипте мы пытаемся разделить 10 на 0, что вызовет исключение ZeroDivisionError. Затем мы перехватываем это исключение и используем isinstance(), чтобы проверить, является ли оно экземпляром ZeroDivisionError или ArithmeticError.

  4. Запустите скрипт, используя следующую команду в терминале:

    python isinstance_exception.py

    Это выведет на терминал сообщение "Caught a ZeroDivisionError!".

    Пример вывода:

    Caught a ZeroDivisionError!
    Program continues...

    Вывод показывает, что функция isinstance() правильно определила исключение как экземпляр ZeroDivisionError. Поскольку ZeroDivisionError является подклассом ArithmeticError, первое условие if выполняется, и выводится соответствующее сообщение.

    Теперь давайте изменим скрипт, чтобы перехватывать более общее исключение.

  5. Измените файл isinstance_exception.py следующим образом:

    try:
        result = int("abc")
    except Exception as e:
        if isinstance(e, ZeroDivisionError):
            print("Caught a ZeroDivisionError!")
        elif isinstance(e, ValueError):
            print("Caught a ValueError!")
        elif isinstance(e, ArithmeticError):
            print("Caught an ArithmeticError!")
        else:
            print("Caught some other exception!")
    
    print("Program continues...")

    В этом измененном скрипте мы пытаемся преобразовать строку "abc" в целое число, что вызовет исключение ValueError.

  6. Запустите скрипт снова, используя ту же команду:

    python isinstance_exception.py

    Это выведет на терминал сообщение "Caught a ValueError!".

    Пример вывода:

    Caught a ValueError!
    Program continues...

    Этот вывод показывает, что функцию isinstance() можно использовать для различения между разными типами исключений и их соответствующей обработки.

Проверка по классам исключений

В этом шаге вы узнаете, как проверять конкретные классы исключений непосредственно в блоках except. Это более прямой и часто более понятный способ обработки исключений по сравнению с использованием функции isinstance().

Когда вы используете конструкцию except ExceptionType as e:, вы сообщаете Python, чтобы он перехватывал только исключения типа ExceptionType или его подклассов.

Давайте создадим скрипт на Python, чтобы продемонстрировать это.

  1. Откройте редактор VS Code.

  2. Создайте новый файл с именем exception_classes.py в директории ~/project.

    ~/project/exception_classes.py
  3. Добавьте следующий код в файл exception_classes.py:

    try:
        result = 10 / 0
    except ZeroDivisionError as e:
        print("Caught a ZeroDivisionError:", e)
    except ArithmeticError as e:
        print("Caught an ArithmeticError:", e)
    except Exception as e:
        print("Caught some other exception:", e)
    
    print("Program continues...")

    В этом скрипте мы пытаемся разделить 10 на 0, что вызовет исключение ZeroDivisionError. У нас есть три блока except: один для ZeroDivisionError, один для ArithmeticError и один для Exception.

  4. Запустите скрипт, используя следующую команду в терминале:

    python exception_classes.py

    Это выведет на терминал сообщение "Caught a ZeroDivisionError: division by zero".

    Пример вывода:

    Caught a ZeroDivisionError: division by zero
    Program continues...

    Вывод показывает, что исключение ZeroDivisionError было перехвачено первым блоком except.

    Теперь давайте изменим скрипт, чтобы вызвать другое исключение.

  5. Измените файл exception_classes.py следующим образом:

    try:
        result = int("abc")
    except ZeroDivisionError as e:
        print("Caught a ZeroDivisionError:", e)
    except ValueError as e:
        print("Caught a ValueError:", e)
    except ArithmeticError as e:
        print("Caught an ArithmeticError:", e)
    except Exception as e:
        print("Caught some other exception:", e)
    
    print("Program continues...")

    В этом измененном скрипте мы пытаемся преобразовать строку "abc" в целое число, что вызовет исключение ValueError.

  6. Запустите скрипт снова, используя ту же команду:

    python exception_classes.py

    Это выведет на терминал сообщение "Caught a ValueError: invalid literal for int() with base 10: 'abc'".

    Пример вывода:

    Caught a ValueError: invalid literal for int() with base 10: 'abc'
    Program continues...

    Этот вывод показывает, что исключение ValueError было перехвачено вторым блоком except.

    Указав класс исключения непосредственно в блоке except, вы можете обрабатывать различные типы исключений четко и организованно. Этот подход обычно предпочтительнее, чем использование функции isinstance() для простой обработки исключений.

Резюме

В этом практическом занятии (лабораторной работе) вы изучили иерархию исключений в Python, которая является важной частью эффективной обработки ошибок. Вы узнали, что исключения организованы в древовидной структуре, где BaseException является базовым классом, а Exception - суперклассом для большинства встроенных исключений.

Вы создали скрипт на Python с именем exception_hierarchy.py, чтобы вывести иерархию исключений, начиная от класса Exception. Запустив этот скрипт, вы увидели древовидную структуру исключений и их взаимосвязи, что дало вам более глубокое понимание того, как исключения организованы в Python.