Ошибки и отладка

Обработка ошибок ввода и отсутствия файла

Содержание курса

Паттерн цикла повторного запроса при некорректном вводе

Одиночный try-except хорош, когда ошибка некритична и программа может продолжить работу без повторной попытки. Но с пользовательским вводом ситуация другая: если человек ввёл не число, нужно не просто вывести сообщение и двигаться дальше — нужно спросить снова. Именно для этого существует паттерн «бесконечный цикл с выходом по успеху».

Идея простая: запускаем while True — цикл, который в норме никогда не остановится сам. Внутри помещаем try-except. Если преобразование прошло успешно, вызываем break — и только тогда. Если возникло исключение, except выводит сообщение, break не вызывается, и цикл идёт на следующую итерацию: пользователь снова видит приглашение ввода.

while True:
    try:
        n = int(input('Введите целое число: '))
        break
    except ValueError:
        print('Это не число. Попробуйте ещё раз.')

print('Вы ввели:', n)

Проследим путь выполнения на двух сценариях.

Сценарий 1 — пользователь вводит 'abc':

  • int('abc') бросает ValueError
  • управление переходит в except, печатается сообщение
  • break не достигается
  • цикл начинается заново

Сценарий 2 — пользователь вводит '42':

  • int('42') возвращает 42, переменная n получает значение
  • следующая строка — break — выполняется
  • цикл завершается
  • print после цикла выводит значение n

Ключевой момент этого паттерна — break является условием выхода, а не просто завершением. Цикл работает не «пока что-то верно», а «пока не получен корректный ввод». Это архитектурное решение: вместо условия в заголовке while логика остановки вынесена внутрь try.

Такой подход хорошо масштабируется. Можно добавить ограничение диапазона значений прямо в блок try, и оно тоже будет под защитой цикла:

while True:
    try:
        age = int(input('Введите ваш возраст (1–120): '))
        if age < 1 or age > 120:
            print('Возраст вне допустимого диапазона.')
            continue
        break
    except ValueError:
        print('Введите целое число.')

print('Возраст принят:', age)

Здесь continue возвращает управление в начало цикла, если число корректное по типу, но не по диапазону. break вызывается только когда оба условия выполнены. Это не усложнение ради усложнения — это демонстрация того, что паттерн гибкий: к нему можно добавлять проверки без изменения общей структуры.