Исключения в Python: что это такое и как с ними работать
«Сигналы тревоги», которые подаёт программа, когда что-то пошло не так.
Иллюстрация: Freepik / Unsplash / Colowgee для Skillbox Media
Что произойдёт, если в коде на Python встретится ошибка? Как программа отправляет сообщения об ошибках программисту и как написать собственный обработчик? За всё это отвечают исключения. Рассказываем, как они работают и как использовать их в своём коде.
Содержание
Как работают исключения в Python
Исключения (exceptions) в Python — это механизм обработки ошибок во время выполнения программы. Они позволяют программе продолжить работу после обнаружения ошибки, а не завершаться аварийно. В Python есть встроенные исключения, которые обрабатывают большинство типовых ошибок.
Рассмотрим такую ситуацию на примере. В коде ниже вызывается функция f1(), внутри которой находится функция f2(). Выполнение будет продолжаться до тех пор, пока интерпретатор не дойдёт до строчки print (y - 2):
Из строки нельзя вычесть число, поэтому в консоли появится информация об ошибке в виде трассировки Traceback с исключением TypeError:
В Python есть встроенные исключения для разных ситуаций. Рассмотрим некоторые из них:
- TypeError — операция или функция применяется к объекту несоответствующего типа.
- ValueError — операция или функция получает аргумент неподходящего значения. К примеру, исключение возникает, если попытаться преобразовать строку в число.
- IndexError — обращение к элементу по несуществующему индексу.
- ZeroDivisionError — деление числа на ноль.
Читайте также:
- FileNotFoundError — Python не может найти файл, который мы хотим открыть.
Это одни из наиболее часто встречающихся встроенных исключений в Python. Полный список можно посмотреть в официальной документации.
Обработка исключений в Python: try, except, finally, else и raise
В Python есть всё необходимое для создания собственных обработчиков исключений. Это полезно, если надо реализовать нетипичное для Python поведение, которое не предусмотрели разработчики. Для этого используются блоки try, except, finally, else и raise:
- С помощью блока try Python проверяет код на наличие исключений. Если в try встречается ошибка, выполнение переходит к первому блоку except.
Читайте также:
- В блоке except содержится код, который будет выполняться, если в блоке try нашлась ошибка.
- В finally помещают код, который будет выполняться независимо от того, была ли найдена ошибка или нет. Часто этот блок используют для работы с файлами, чтобы закрыть документ.
- Код в else выполняется, если try не нашёл исключений.
- Ключевое слово as при обработке ошибок используется для присвоения исключению переменной. К примеру, напишем собственное исключение для обработки деления на ноль. Ошибку назовём ZeroDivisionError и присвоим переменной e. Теперь к ней можно получить доступ для печати названия ошибки в консоль.
- Команда raise в Python используется для принудительного вызова исключения. Это может быть полезно, если мы столкнулись с условием, которое должно остановить выполнение программы или вызвать ошибку.
Обработка нескольких исключений
С помощью блоков except можно обрабатывать несколько исключений разными способами. Каждый except соответствует определённому типу ошибки.
Например, если в блоке try происходит исключение TypeError, будет выполнен первый блок except, и аналогично для ZeroDivisionError:
Иногда возникает необходимость обрабатывать несколько типов исключений одинаковым образом. В этом случае можно перечислить эти исключения в одном блоке except, разделив их запятыми:
Блок except без указания конкретного типа исключения будет обрабатывать все исключения, которые не были обработаны в предыдущих блоках except, в том числе прерывание с клавиатуры, системный выход и другое.
Такая форма конструкции практически не используется. Вместо этого разработчики предпочитают except Exception. Так можно сначала обработать конкретные исключения, а потом уже всё остальное.
К примеру, в первом блоке except обработаем исключение TypeError — будем выводить в консоль сообщение Обнаружена ошибка TypeError. Второй блок except будет отлавливать остальные исключения и выводить Что-то пошло не так:
Начинать обработку следует с более узких классов исключений, например TypeError. Если начать с более широкого класса, такого как Exception, то всегда будет срабатывать первый блок except:
Как игнорировать ошибки в Python
Вот написали вы код, запускаете его, а Python сыпет ошибки в консоль. Вы уверены, что это фичи, а не баги, но это надо как-то донести до интерпретатора. Для таких случаев в Python есть механизм игнорирования ошибок.
Читайте также:
Для игнорирования исключений в Python можно использовать блок try/except. При этом нужно оставить его пустым или записать в нём оператор-заглушку pass, который ничего не делает.
В Python нельзя делить на ноль, но с помощью механизма игнорирования ошибок этого можно избежать. Попробуем разделить единицу на каждое число из списка. Заметьте, что среди чисел есть ноль, поэтому выполнение должно вызвать исключения ZeroDivisionError.
Читайте также:
Мы же обработаем эту ошибку с помощью блока except. Используем оператор pass, чтобы Python проигнорировал ошибку:
В результате получим:
Важно помнить, что не стоит полностью игнорировать ошибки. Это может привести к тому, что скрытые проблемы в коде останутся незамеченными и будет сложнее отлаживать и поддерживать программу в долгосрочной перспективе.
Лучше обрабатывать ошибки должным образом: исправлять проблему, выводить полезное сообщение об ошибке или отлавливать конкретные исключения.
Создание собственных исключений
Иногда надо реализовать собственный обработчик ошибок с помощью исключений. Это делает код более безопасным и поддерживаемым. Для создания собственного исключения достаточно определить новый класс, который наследуется от базового класса Exception или от любого другого встроенного исключения:
Читайте также:
В примере выше ValidationError — исключение, которое не делает ничего, кроме наследования поведения стандартного исключения Exception.
Продолжим код:
В этом примере функция person_age использует созданное нами исключение ValidationError для проверки корректности введённого возраста. Вызов функции с некорректными данными приводит к генерации исключения ValidationError, которое затем можно перехватить и обработать.
Что в итоге
Исключения в Python полезны для написания отказоустойчивого кода. Они позволяют обрабатывать ошибки при выполнении программы и гарантировать, что код продолжит свою работу даже в неожиданных ситуациях. Однако важно понимать, что не все ошибки можно или нужно обрабатывать, — иногда лучше позволить программе завершиться с ошибкой, чтобы можно было быстро узнать о проблеме и исправить её.