Python: уроки, справочник и задачи

Ошибки и исключения Python: список с объяснениями

Раздел: Исключения и отладка · Обновлено 31.10.2026

Коды ошибок Python - это не числа, как в HTTP, а имена классов исключений: TypeError, KeyError, ZeroDivisionError и другие. По имени и тексту сообщения можно точно понять, что сломалось и в какой строке. В статье разобрано, как читать traceback, чем синтаксические ошибки отличаются от исключений во время работы, приведена таблица встроенных исключений с причинами, а также числовые коды errno и коды завершения программы.

Ошибки и исключения Python: список с объяснениями
Фото: Lklundin / CC BY-SA 4.0, Wikimedia Commons
Содержание статьи
  1. Как читать сообщение об ошибке
  2. Синтаксические ошибки
  3. Исключения во время выполнения
  4. Таблица встроенных исключений
  5. Иерархия исключений
    1. BaseException и Exception
    2. Числовые коды errno
  6. Код завершения программы
  7. Как перехватить ошибку
  8. Частые вопросы
    1. Чем ошибка отличается от исключения?
    2. Как вывести полный traceback, не останавливая программу?
    3. Почему появляется ModuleNotFoundError, если библиотека установлена?
    4. Какой код выхода у программы с необработанным исключением?
    5. Как узнать тип пойманного исключения?

Как читать сообщение об ошибке

Когда программа падает, Python печатает traceback - след вызовов от точки входа до места сбоя. Читать его удобнее снизу вверх: последняя строка содержит тип исключения и пояснение, а строки над ней показывают файл, номер строки и функцию.

def average(nums):
    return sum(nums) / len(nums)

print(average([]))
Traceback (most recent call last):
  File "main.py", line 4, in <module>
    print(average([]))
  File "main.py", line 2, in average
    return sum(nums) / len(nums)
           ~~~~~~~~~~^~~~~~~~~~~
ZeroDivisionError: division by zero

Здесь видно, что ошибка возникла в функции average на второй строке, а вызвала ее четвертая строка модуля. Начиная с Python 3.11 интерпретатор подчеркивает знаками ~ и ^ конкретную часть выражения, которая привела к сбою. Это особенно полезно в длинных строках с несколькими операциями.

Синтаксические ошибки

Синтаксическая ошибка означает, что код нарушает правила языка, и Python не может его даже разобрать. Программа не запустится вообще: ни одна строка не выполнится, пока ошибка не исправлена. Типичные причины: пропущенное двоеточие, незакрытая скобка или кавычка, опечатка в ключевом слове.

for i in range(3)
    print(i)

# SyntaxError: expected ':'

В эту же группу входят IndentationError (неверный отступ, например тело цикла не сдвинуто) и TabError (в одном блоке смешаны табы и пробелы). Современные версии Python пишут понятные подсказки вроде '(' was never closed, поэтому текст сообщения стоит читать целиком. Правила отступов подробно описаны в статье про идентификаторы, комментарии и отступы.

Исключения во время выполнения

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

open("missing.txt")
# FileNotFoundError: [Errno 2] No such file or directory: 'missing.txt'

int("12a")
# ValueError: invalid literal for int() with base 10: '12a'

"Возраст: " + 25
# TypeError: can only concatenate str (not "int") to str

Отдельно стоят логические ошибки: программа работает без исключений, но выдает неверный результат, например из-за перепутанного условия или неправильной границы range(). Python о них не сообщает, их ловят тестами и отладкой.

Таблица встроенных исключений

В таблице собраны исключения, которые встречаются чаще всего, и типичные причины их появления.

ИсключениеКогда возникает
AttributeErrorу объекта нет такого атрибута или метода, например None.split()
IndexErrorиндекс за пределами списка, строки или кортежа
KeyErrorв словаре нет запрошенного ключа
NameErrorпеременная или функция не определена, часто из-за опечатки
UnboundLocalErrorлокальная переменная используется до присваивания внутри функции
TypeErrorоперация применена к неподходящему типу или передано не то число аргументов
ValueErrorтип подходит, но значение недопустимо: int("abc")
ZeroDivisionErrorделение или остаток от деления на ноль
FileNotFoundErrorфайл или папка не найдены
PermissionErrorнет прав на чтение, запись или удаление
ModuleNotFoundErrorмодуль не установлен или имя написано с ошибкой
ImportErrorмодуль найден, но нужного имени в нем нет
RecursionErrorпревышена глубина рекурсии, по умолчанию около 1000 вызовов
StopIterationnext() вызван у исчерпанного итератора
UnicodeDecodeErrorбайты не удалось прочитать в указанной кодировке
OverflowErrorрезультат вычисления с float слишком велик
MemoryErrorпрограмме не хватило оперативной памяти
AssertionErrorусловие в операторе assert оказалось ложным
KeyboardInterruptпользователь прервал программу клавишами Ctrl+C

Полный список с описанием каждого класса приведен в разделе Built-in Exceptions официальной документации.

Иерархия исключений

Все исключения - это классы, унаследованные от BaseException. Благодаря наследованию один блок except может поймать целую группу родственных ошибок.

BaseException и Exception

Прямо от BaseException наследуются системные исключения SystemExit, KeyboardInterrupt и GeneratorExit. Обычные ошибки программы наследуются от Exception, поэтому except Exception не мешает остановить скрипт через Ctrl+C. Несколько полезных групп:

print(KeyError.__mro__)
# (<class 'KeyError'>, <class 'LookupError'>, <class 'Exception'>,
#  <class 'BaseException'>, <class 'object'>)

Числовые коды errno

Ближе всего к привычным кодам ошибок атрибут errno у OSError. Это номер системной ошибки, а модуль errno дает для него понятные имена: ENOENT (нет такого файла), EACCES (доступ запрещен), EEXIST (файл уже существует).

import errno

try:
    open("missing.txt")
except OSError as e:
    print(e.errno, errno.errorcode[e.errno])  # 2 ENOENT

Код завершения программы

Когда скрипт заканчивает работу, операционная система получает код выхода. Значение 0 означает успех, любое другое число сигналит о проблеме. Если исключение не перехвачено, интерпретатор печатает traceback и завершается с кодом 1. Собственный код можно задать через sys.exit().

import sys

if len(sys.argv) < 2:
    print("Укажите имя файла", file=sys.stderr)
    sys.exit(2)

print("Обрабатываю", sys.argv[1])

В командной строке код последней программы показывает echo $? в Linux и macOS или echo %ERRORLEVEL% в Windows. Код 2 по традиции означает неправильные аргументы, так же поступает модуль argparse.

Как перехватить ошибку

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

def to_int(text):
    try:
        return int(text)
    except ValueError:
        print(f"Не число: {text!r}")
        return 0

print(to_int("42"), to_int("4x"))

Блоки else, finally и перехват нескольких типов разобраны в статье обработка исключений, а создание своих классов ошибок и raise описаны на странице собственные исключения.

Частые вопросы

Короткие ответы на вопросы о кодах ошибок и исключениях в Python.

Чем ошибка отличается от исключения?

Синтаксическая ошибка мешает запуску программы, ее нельзя перехватить в том же файле. Исключение возникает при выполнении корректного кода и обрабатывается через try/except.

Как вывести полный traceback, не останавливая программу?

Внутри блока except вызовите traceback.print_exc() из модуля traceback или используйте logging.exception(), который запишет сообщение вместе со стеком вызовов.

Почему появляется ModuleNotFoundError, если библиотека установлена?

Чаще всего пакет установлен в другой интерпретатор или виртуальное окружение. Ставьте пакеты командой python -m pip install имя тем же Python, которым запускаете скрипт.

Какой код выхода у программы с необработанным исключением?

Код 1. Успешное завершение возвращает 0, а sys.exit(n) позволяет задать любое число от 0 до 255.

Как узнать тип пойманного исключения?

Запишите except Exception as e: и выведите type(e).__name__ и e: первое даст имя класса, второе текст сообщения.