try except в Python: простая обработка ошибок
Автор: Казачкин Даниил Михайлович · Обновлено
Блок try содержит операцию, которая может завершиться ожидаемой ошибкой. except перехватывает конкретный тип и выбирает понятное действие. Обработка не должна скрывать программные дефекты, поэтому ловят узкие исключения и помещают в try минимально рискованный фрагмент.
Безопасное деление введённого числа
text = '0'
try:
number = int(text)
result = 100 / number
except ValueError:
print('Нужно целое число')
except ZeroDivisionError:
print('На ноль делить нельзя')
else:
print(result)Для текста 0 ожидается:
На ноль делить нельзяValueError отвечает за неверную запись числа, ZeroDivisionError — за нулевой делитель. Блок else выполняется только без исключения.
Почему except без типа вреден
Голый except перехватывает почти всё, включая неожиданные проблемы, и затрудняет поиск причины. Запись except Exception тоже слишком широка для простого преобразования. Не используйте pass, если пользователь должен узнать, что данные не приняты.
Ошибка может возникнуть и внутри самого обработчика. Проверяйте каждую ветку отдельным вводом. finally выполняется в любом случае и нужен для обязательного завершения действия, но with часто лучше управляет файлами.
Три обязательных сценария
Прочитайте возраст и выведите возраст через год. Для текста вместо числа покажите подсказку, отрицательное число обработайте обычным if после успешного преобразования. Проверьте 15, abc и -2. Затем добавьте повторный ввод через while, который заканчивается только после корректного неотрицательного значения. Убедитесь, что исключение не используется для обычной проверки диапазона.
Граница ответственности except
Разбейте программу на три шага: чтение текста, преобразование числа и вычисление. Поместите в try только преобразование и перехватите ValueError. Проверку диапазона выполните обычным if, а неожиданные ошибки не ловите. Затем намеренно добавьте опечатку имени после преобразования: traceback должен сохраниться, иначе обработчик слишком широк. Для цикла повторного ввода подсчитайте попытки и остановитесь после трёх неудач. Пользователь получает понятное сообщение, а разработчик не теряет сведения о дефекте. Сформулируйте, какое исключение считается ожидаемой частью сценария и почему остальные проходят выше.
Практикум: узкая обработка ошибки ввода
Попросите возраст и повторяйте ввод, пока не получите целое число от 0 до 120. Поместите в try только преобразование, а проверку диапазона выполните отдельно. Сравните except ValueError с широким except Exception: второй может скрыть дефект, не связанный с пользователем. Проверьте пустую строку, 12.5, -1, 121 и 18. Сообщения должны различать неверный формат и недопустимый диапазон. После успешного ввода цикл завершается один раз.
Контрольная точка
Какая минимальная операция способна вызвать ожидаемый ValueError? Чем меньше блок try, тем точнее известно, какая строка привела к предусмотренному пути обработки.
Частые вопросы
Нужно ли ловить любую ошибку, чтобы программа не падала?
Нет. Обрабатывайте только ошибки, для которых есть осмысленный следующий шаг. Неожиданный дефект лучше увидеть с traceback, чем превратить в неверный результат или бесконечный повтор.