🐍
Основы
Опубликовано:
13.04.2026
Обновлено:
30.04.2026

try и except в Python — перехват исключений с примерами

Илья Новиков

Любая программа рано или поздно сталкивается с ошибками. Пользователь вводит текст вместо числа, файл не находится на диске, сервер не отвечает. Если не предусмотреть такие ситуации — программа просто упадёт. Python предлагает механизм try/except, который позволяет перехватывать ошибки и реагировать на них без аварийного завершения.

Что такое исключение

Когда Python натыкается на операцию, которую не может выполнить, он генерирует исключение. Это специальный объект, описывающий ошибку. Если исключение никто не перехватил — интерпретатор останавливает выполнение и выводит traceback: цепочку вызовов, которая привела к сбою.

Вот типичный пример. Программа просит пользователя ввести температуру по Фаренгейту и переводит её в градусы Цельсия:

inp = input('Enter Fahrenheit Temperature: ')
fahr = float(inp)
cel = (fahr - 32.0) * 5.0 / 9.0
print(cel)

Пока пользователь вводит числа, всё работает штатно. Но стоит ввести «fred» — и Python выбросит ValueError:

Traceback (most recent call last):
  File "fahren.py", line 2, in <module>
    fahr = float(inp)
ValueError: could not convert string to float: 'fred'

Traceback — штука полезная для разработчика: видно файл, строку и тип ошибки. Но пользователь видит непонятное сообщение, а программа прекращает работу.

Базовый синтаксис try/except

Конструкция try/except устроена просто. В блок try помещается код, который может вызвать ошибку. В блок except — код, который выполнится, если ошибка произойдёт.

inp = input('Enter Fahrenheit Temperature: ')
try:
    fahr = float(inp)
    cel = (fahr - 32.0) * 5.0 / 9.0
    print(cel)
except:
    print('Please enter a number')

Теперь при вводе «fred» программа не падает, а выводит вежливую просьбу:

$ python fahren2.py
Enter Fahrenheit Temperature: 72
22.22222222222222

$ python fahren2.py
Enter Fahrenheit Temperature: fred
Please enter a number

Python выполняет блок try построчно. Если всё прошло гладко — блок except пропускается целиком. Если на какой-то строке возникло исключение — Python немедленно переходит в except, а остаток try игнорируется.

Зачем указывать тип исключения

Голый except без указания типа ошибки перехватывает вообще всё. На первый взгляд удобно, на практике — рискованно. Представьте ситуацию: у вас опечатка в имени переменной внутри try. Python выбросит NameError, а ваш except молча проглотит его. Вы потратите время на поиск бага, которого формально «нет».

Поэтому в рабочих проектах указывают конкретный тип:

try:
    fahr = float(inp)
except ValueError:
    print('Это не число. Попробуйте ещё раз.')

Распространённые типы исключений

Python содержит несколько десятков встроенных исключений. Вот те, с которыми сталкиваешься чаще остальных:

  • ValueError — значение не подходит по смыслу. Попытка превратить строку «hello» в число через int() или float().
  • TypeError — операция применена к объекту неподходящего типа. Классика: 'abc' + 5.
  • IndexError — обращение к элементу списка по несуществующему индексу.
  • KeyError — обращение к словарю по ключу, которого нет.
  • FileNotFoundError — попытка открыть файл, которого не существует на диске.
  • ZeroDivisionError —  деление на ноль.

Перехват нескольких исключений

Иногда один участок кода может упасть по разным причинам. Первый подход — несколько блоков except подряд:

try:
    value = int(input('Введите номер элемента: '))
    items = ['яблоко', 'банан', 'вишня']
    print(items[value])
except ValueError:
    print('Введите целое число')
except IndexError:
    print('Такого элемента нет в списке')

Второй подход — кортеж исключений, когда реакция одинаковая:

try:
    result = int(input('Число: ')) / int(input('Делитель: '))
except (ValueError, ZeroDivisionError):
    print('Некорректный ввод или деление на ноль')

Получение информации об ошибке

Ключевое слово as позволяет сохранить объект исключения в переменную:

try:
    number = int('not_a_number')
except ValueError as err:
    print(f'Ошибка: {err}')

Вывод: Ошибка: invalid literal for int() with base 10: 'not_a_number'

В продакшене это используют для логирования. Сообщение уходит в лог-файл, а пользователю показывают что-нибудь дружелюбное.

Блок else

Блок else выполняется, только если в try не возникло ни одного исключения:

try:
    value = int(input('Введите число: '))
except ValueError:
    print('Это не число!')
else:
    print(f'Вы ввели {value}. Его квадрат: {value ** 2}')

Код в else не защищён блоком except. Если в нём возникнет ошибка — она уйдёт дальше по стеку, а не будет проглочена. Так вы разделяете «опасный» участок и «безопасный».

Блок finally

Блок finally выполняется всегда — было исключение или нет. Его назначение — освобождение ресурсов:

fhand = None
try:
    fhand = open('data.txt')
    content = fhand.read()
    print(content)
except FileNotFoundError:
    print('Файл не найден')
finally:
    if fhand is not None:
        fhand.close()
        print('Файл закрыт')

Практика: безопасное чтение файла

Открытие файлов — одно из самых частых мест применения try/except. Пользователь может указать несуществующее имя, у программы может не хватить прав на чтение:

fname = input('Enter the file name: ')
try:
    fhand = open(fname)
except:
    print('File cannot be opened:', fname)
    exit()

count = 0
for line in fhand:
    if line.startswith('Subject:'):
        count = count + 1

print('There were', count, 'subject lines in', fname)

Такой подход называют «питоническим». В Python принято не проверять условия заранее, а пробовать выполнить операцию и разбираться с последствиями — EAFP (Easier to Ask Forgiveness than Permission).

Практика: валидация ввода в цикле

while True:
    inp = input('Введите целое число: ')
    try:
        value = int(inp)
        break
    except ValueError:
        print('Не похоже на целое число, попробуйте снова')

print(f'Спасибо! Вы ввели: {value}')

Цикл крутится, пока пользователь не введёт корректное число. После успешного int() — break, цикл завершается.

Практика: обработка списка с грязными данными

data = ['10', 'двадцать', '30', 'сорок', '50', '???']
total = 0
skipped = 0

for item in data:
    try:
        total += float(item)
    except ValueError:
        skipped += 1

print(f'Сумма: {total}, пропущено: {skipped}')

Результат: Сумма: 90.0, пропущено: 3. Программа обработала то, что смогла, и сообщила, сколько элементов проигнорировала.

Паттерн «страж» и короткое замыкание

Python поддерживает «короткое замыкание» (short-circuit evaluation) — оператор and прекращает вычисление, встретив ложное значение:

x = 6
y = 0

if y != 0 and x / y > 2:
    print('Результат больше двух')
else:
    print('Деление невозможно или результат мал')

Выражение y != 0 стоит первым. Если y равен нулю — Python не дойдёт до деления. Порядок условий критичен.

Вложенные try/except

try:
    fname = input('Имя файла: ')
    fhand = open(fname)
    try:
        data = fhand.read()
        numbers = [float(x) for x in data.split()]
        print(f'Среднее: {sum(numbers) / len(numbers)}')
    except ValueError:
        print('В файле есть нечисловые данные')
    except ZeroDivisionError:
        print('Файл пуст')
    finally:
        fhand.close()
except FileNotFoundError:
    print(f'Файл {fname} не существует')

Внешний try ловит ошибку открытия. Внутренний — ошибки разбора. Три уровня вложенности — сигнал, что код пора разбить на функции.

Генерация исключений через raise

def set_age(age):
    if age < 0:
        raise ValueError('Возраст не может быть отрицательным')
    return age


try:
    user_age = set_age(-5)
except ValueError as err:
    print(err)

raise создаёт исключение и отправляет его вверх по стеку вызовов. Полезен для валидации аргументов функций.

Типичные ошибки при работе с исключениями

  • Слишком широкий except — голый except: ловит даже KeyboardInterrupt (Ctrl+C), и пользователь не сможет остановить скрипт.
  • Пустой except — except: pass скрывает ошибку навсегда. Как минимум пишите в лог.
  • Слишком много кода в try — сложнее определить, какая строка упала. Оборачивайте минимум.
  • Исключения вместо условий — try/except не замена  if/else. Если проверка возможна заранее — проверяйте.

Когда try/except нужен

  • Ввод пользователя — нет гарантий корректности данных.
  • Файловые операции — файл может отсутствовать или быть заблокирован.
  • Сетевые запросы — сервер не ответил, соединение оборвалось.
  • Парсинг данных — формат может не совпасть с ожидаемым.
  • Работа с базами данных — запрос не вернул результат, таблица не существует.

Освоив этот механизм, вы перестанете воспринимать ошибки как катастрофу. Ошибка — сигнал. try/except — способ этот сигнал услышать, обработать и двигаться дальше.

Нашли ошибку?
Напишите нам info@codesrc.ru
Следите за нами в соцсетях:

Читайте также