Исключения играют важную роль в программировании. Они помогают обрабатывать непредвиденные ошибки и предотвращать критические сбои.
В этом уроке мы рассмотрим, как работают исключения, как создавать собственные исключения и как их обрабатывать.
Исключения и перехват исключений
Исключения в Python могут быть сгенерированы и перехвачены с помощью конструкции try/except
. Это похоже на то, как работают исключения в других языках.
Пример простого исключения:
try:
do_something_dangerous()
except Exception as e:
print("Something happened", e)
В данном примере функция do_something_dangerous()
может выбросить исключение. Мы оборачиваем ее вызов в блок try
. Если исключение выбрасывается, оно перехватывается блоком except
. В итоге мы печатаем сообщение о том, что произошло, вместе с информацией об исключении.
Но как понять что случилось? Иногда это важно. Разные ошибки могут приводить к разному поведению программы. Кроме того, не все ошибки требуют обработки в текущем месте программы.
Разделять ошибки можно с помощью разных классов, наследующихся от класса Exception
. По техническим причинам реализовать этот интерфейс напрямую нельзя, поэтому остается только один путь — наследование.
Обработка стандартных исключений играет ключевую роль в создании устойчивого кода. Однако иногда возникает потребность создать свои исключения для точного контроля над ошибками в программе.
Создание собственных исключений
Мы можем определить свои исключения, создав новый класс, который наследуется от базового класса исключений:
class MyException(Exception):
pass
При этом в исключениях редко нужно добавлять или изменять поведение. Основная цель использования наследования исключений — описание всех возможных типов ошибок.
Теперь посмотрим, как этим можно воспользоваться:
try:
# Какой-то код
except MyException as e:
# Делаем что-нибудь одно
except Exception as e:
# Делаем что-нибудь другое
Если какой-то код генерирует исключение MyException
, мы обрабатываем его особым образом. В противном случае мы обрабатываем остальные исключения блоком except Exception
.
Можно разделять ошибки с помощью разных классов, наследующихся от базового класса Exception
:
class MyError(Exception):
pass
class FirstError(MyError):
pass
class SecondError(MyError):
pass
Рассмотрим, как использовать одновременно все эти классы исключений:
try:
# Код, который может вызвать исключение
pass
except FirstError:
# Обрабатываем FirstError
pass
except SecondError:
# Обрабатываем SecondError
pass
except MyError:
# Обрабатываем MyError
pass
except Exception as e:
# Во всех остальных случаях, например, бросаем исключение снова
raise e
Обработка любого базового исключения автоматически влечет за собой обработку всех наследников текущего класса. Например, если перехватить MyError
, этот блок также будет реагировать на FirstError
и SecondError
. Чтобы избежать этой проблемы, нужно разместить обработчики для FirstError
и SecondError
перед обработчиком MyError
.
В самом Python уже есть иерархия исключений, которая позволяет разделять реакцию на разные типы ошибок.
При создании собственных исключений рекомендуется создавать высокоуровневое исключение, которое наследуется от Exception
или BaseException
. Далее все специфические исключения вашей программы или библиотеки могут наследоваться от этого высокоуровневого исключения. Это позволяет легко группировать и обрабатывать исключения по их типу. А также позволяет изолировать обработку ошибок конкретной библиотеки буквально одним блоком except
.
Но что делать, когда возникает ситуация, требующая выполнения определенных действий независимо от наличия ошибок в коде? Например, когда необходимо освободить ресурсы или выполнить другие важные операции. Для решения этой проблемы у нас есть конструкция finally
, которая обеспечивает гарантированное выполнение кода, независимо от того, возникло исключение или нет.
Блок finally
В некоторых ситуациях нужно продолжить работу независимо от того, возникло исключение или нет. Используя только try/except
, эту задачу нельзя выполнить без дублирования. Придется размещать код как после всей конструкции try/except
, так и в каждом блоке except
.
В Python для этого есть блок finally
, который будет выполнен независимо от того, возникло исключение или нет:
try:
# Какой-то код
except MyException as e:
# Делаем что-нибудь одно
finally:
# Вызовется в любом случае
Это полезно для освобождения ресурсов или выполнения действий, которые должны произойти независимо от результата выполнения кода.
Выводы
Обработка исключений — важный инструмент для создания надежных и устойчивых программ. Они позволяют программе гибко реагировать на ошибки, обеспечивая гладкое выполнение. Понимание того, как использовать исключения в Python, является важной частью развития навыков программирования на этом языке.
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
- Статья «Как учиться и справляться с негативными мыслями»
- Статья «Ловушки обучения»
- Статья «Сложные простые задачи по программированию»
- Вебинар «Как самостоятельно учиться»
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.