Исключения углублённо
Превратите сбои в управляемые и восстановимые события
Главная идея: исключение — это способ Python сообщить, что что-то пошло не так, в виде значения, которое поднимается вверх по стеку вызовов. Вместо возврата кодов ошибок и их ручной проверки вы позволяете сбою прервать обычный ход выполнения, а затем перехватываете его именно там, где можете сделать что-то полезное. С
try/except вы уже познакомились в начальном курсе; здесь вы освоите полный жизненный цикл: try, except, else, finally, намеренный вызов ошибок через raise, проектирование собственных типов исключений и связывание одного сбоя с другим.
К концу вы сможете:
- использовать все четыре блока —
try,except,else,finally— и объяснить назначение каждого, - перехватывать конкретные типы исключений (и понимать, почему пустой
except:— ловушка), - намеренно вызывать исключения через
raise, включая повторный вызов, - проектировать собственные исключения, наследуясь от
Exception, - сохранять исходную причину с помощью связывания исключений (
raise ... from ...).
1. Полная анатомия: try / except / else / finally
Полный обработчик исключений состоит максимум из четырёх частей. Обязательны только try и хотя бы один except (или finally); else и finally необязательны, но очень полезны.
try:
# 1. рискованная работа
value = int(user_input)
except ValueError:
# 2. выполняется, ТОЛЬКО если в try возникло подходящее исключение
print("That was not a whole number.")
else:
# 3. выполняется, ТОЛЬКО если try завершился БЕЗ исключения
print("You entered", value)
finally:
# 4. выполняется ВСЕГДА — при успехе, сбое и даже return
print("Done validating.")
Ключевое различие, которое многие упускают, — между else и просто дописыванием кода в конец try:
tryдолжен содержать только те строки, которые могут дать сбой. Держите его коротким, чтобы точно знать, что именно перехватываетexcept.exceptобрабатывает один вид сбоя. Их может быть несколько, они проверяются сверху вниз; побеждает первый подходящий.elseсодержит действия «всё сработало». Поскольку он выполняется только при успешномtry, исключение, возникшее здесь, НЕ будет перехвачено расположенным вышеexcept— и в этом весь смысл.finallyпредназначен для очистки, которая должна произойти при любом исходе: закрытие файлов, освобождение блокировок, восстановление состояния. Он выполняется, даже если вы делаетеreturnвнутриtry.