Python

Как читать Traceback в Python: находить строку и причину ошибки

Разбираем Traceback снизу вверх: тип исключения, файл, номер строки, стек функций, значения переменных и цепочки ошибок.

Кодик

Автор

6 мин чтения

Чтобы понять Traceback, начните с последней строки: там указан тип исключения и причина. Затем поднимитесь к ближайшей строке с вашим файлом и номером строки. Сам Traceback не является отдельной ошибкой. Это маршрут вызовов, по которому Python дошёл до сбоя. Если читать его в правильном порядке, длинное сообщение превращается в несколько конкретных подсказок.

Новичок часто видит десять строк красного текста и начинает исправлять первую. Обычно полезная точка находится внизу. Последняя строка отвечает на вопрос «что случилось», строка над ней показывает «где проявилось», а более ранние кадры объясняют «как программа туда пришла».

1Причина

Последняя строка: класс исключения и его сообщение.

2Место

Ближайший нижний кадр: файл, номер строки и выражение.

3Путь

Кадры выше: функции, которые последовательно вызвали друг друга.

Из чего состоит Traceback в Python

def price_per_item(total, count):
    return total / count

print(price_per_item(900, 0))

# Traceback (most recent call last):
#   File "shop.py", line 4, in <module>
#     print(price_per_item(900, 0))
#           ^^^^^^^^^^^^^^^^^^^^^^
#   File "shop.py", line 2, in price_per_item
#     return total / count
#            ~~~~~~^~~~~~~
# ZeroDivisionError: division by zero
ФрагментЧто он означаетПервое действие
Traceback (most recent call last)Ниже перечислен стек вызововНе исправлять эту строку
File "shop.py", line 2Сбой проявился во второй строке файлаОткрыть файл и сверить код
in price_per_itemСтрока выполнялась внутри функцииПроверить её аргументы
ZeroDivisionErrorТип исключенияИскать деление на ноль
division by zeroКороткое описание причиныПонять, почему count равен нулю

Анатомия Traceback в Python с причиной, строкой и стеком вызовов
У сообщения три уровня: причина внизу, место над ней и путь вызовов выше.

Номер строки указывает на место проявления. Причина может появиться раньше. Если в деление пришёл ноль, строка с оператором / исправна синтаксически. Нужно проверить, откуда получен аргумент count и при каких данных он стал нулём.

Как читать Traceback снизу вверх

Алгоритм на 60 секунд
  1. Скопируйте название исключения из последней строки, например TypeError.
  2. Прочитайте сообщение после двоеточия, не пересказывая его своими словами.
  3. Поднимитесь к последнему кадру File и откройте указанный номер строки.
  4. Отметьте значения переменных, которые участвовали в выделенном выражении.
  5. Если строка находится в библиотеке, поднимайтесь до ближайшего кадра вашего проекта.
  6. Повторите тот же ввод после одной правки, чтобы проверить именно эту гипотезу.

Например, сообщение TypeError: can only concatenate str (not "int") to str уже содержит конфликт типов. Найдите в проблемной строке оператор +, затем проверьте значения через print(type(value), repr(value)). Функция repr покажет кавычки, пробелы и управляющие символы, которые обычный вывод скрывает.

age = input('Сколько вам лет? ')
print(type(age), repr(age))

# Результат при вводе 16:
# <class 'str'> '16'

next_age = int(age) + 1
print(next_age)
# 17

Порядок чтения Traceback от исключения к значениям переменных
Не угадывайте исправление по названию ошибки: сначала свяжите сообщение с реальными значениями в проблемной строке.

Хорошая диагностика заканчивается проверяемой фразой

Не «Python сломал сложение», а «input() вернул строку '16', а код пытался прибавить к ней целое число». Из такой формулировки сразу следует проверка: преобразовать ввод через int и повторить тот же сценарий.

Что означают несколько файлов и функций в стеке

Каждый блок File ... line ... in ... называется кадром стека. Первый кадр показывает ранний вызов, последний находится ближе всего к исключению. Длинный стек не означает много ошибок: одна проблема могла пройти через пять функций и проявиться в шестой.

def parse_count(raw):
    return int(raw)

def make_order(raw_count):
    count = parse_count(raw_count)
    return {'count': count}

print(make_order('три'))

# Последние строки Traceback:
#   File "orders.py", line 5, in make_order
#     count = parse_count(raw_count)
#   File "orders.py", line 2, in parse_count
#     return int(raw)
# ValueError: invalid literal for int() with base 10: 'три'
КадрКакой вопрос задатьЧто проверить
<module>С чего начался сценарий?Входные данные и вызов верхнего уровня
Ваша функцияКакое значение передано дальше?Аргументы, ветки if, результат предыдущего шага
Последняя ваша функцияКакое выражение упало?Тип и содержимое конкретной переменной
Файл установленной библиотекиЧто передал мой код?Последний кадр проекта перед входом в библиотеку

Стек вызовов Python от основного файла к функции с ошибкой
Идите от последнего кадра к вызывающему, пока не найдёте место, где неверное значение появилось или не было проверено.

Не правьте код библиотеки первым делом. Если нижний кадр лежит в site-packages, библиотека могла корректно отклонить неверный аргумент. Найдите последний кадр с файлом вашего проекта и сопоставьте переданные данные с документацией функции.

Две ошибки подряд и цепочка исключений

Иногда консоль показывает два Traceback, разделённых фразой During handling of the above exception или The above exception was the direct cause. Это цепочка: код перехватил первое исключение, а затем возникло или было явно создано второе. Активной проблемой считается последняя нижняя ошибка, но верхняя объясняет её первопричину.

def read_limit(raw):
    try:
        return int(raw)
    except ValueError as error:
        raise ValueError('Лимит должен быть целым числом') from error

read_limit('десять')

# Сначала Python покажет ValueError от int('десять'),
# затем фразу про direct cause,
# затем ValueError: Лимит должен быть целым числом
Исправлять первую строку сообщения

Заголовок Traceback ничего не говорит о причине. Начните с последней строки и последнего полезного кадра.

Удалять строку, которая упала

Так симптом исчезает вместе с нужной функцией. Проверьте данные, контракт функции и допустимые значения.

Окружать весь файл except Exception

Широкий перехват скрывает класс, строку и стек. Перехватывайте только ожидаемое исключение там, где умеете его обработать.

Менять пять мест одновременно

После пачки правок нельзя понять, какая гипотеза была верной. Делайте одно изменение и повторяйте исходный сценарий.

Цепочка полезна, когда добавляет контекст

Конструкция raise ... from error сохраняет исходную причину и добавляет понятное сообщение уровня вашей программы. Пользователь видит «лимит должен быть числом», а разработчик не теряет исходный ValueError.

Чек-лист: что приложить к вопросу об ошибке

Скриншот одной последней строки редко помогает. Тому, кто разбирает ошибку, нужен весь Traceback, небольшой воспроизводимый код, команда запуска и входные данные. Секреты, токены, адреса закрытых сервисов и личные пути перед отправкой удалите.

Минимальный набор для разбора
  1. Скопируйте Traceback целиком как текст, от заголовка до последней строки.
  2. Укажите команду запуска: например, python orders.py.
  3. Оставьте минимальный код, который всё ещё воспроизводит проблему.
  4. Добавьте точный ввод и ожидаемый результат.
  5. Напишите версию Python из python --version и название среды.
  6. Повторите запуск и убедитесь, что сообщение осталось тем же.
SyntaxError читается немного иначе. Если Python не смог разобрать файл, полного стека вызовов может не быть. Тогда смотрите на файл, номер строки, указатель и сообщение синтаксической ошибки. Для отступов используйте отдельную инструкцию про IndentationError.
Короткие ответы
Traceback и ошибка это одно и то же?

Нет. Исключение является событием ошибки, а Traceback показывает стек вызовов, который привёл к этому месту.

Почему читать нужно снизу?

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

Какой файл исправлять, если в стеке есть библиотека?

Сначала найдите последний кадр своего проекта и проверьте аргументы, которые ваш код передал библиотеке.

Почему номер строки изменился после правки?

После добавления или удаления строк координаты сдвигаются. Запустите актуально сохранённый файл и работайте с новым сообщением.

Можно ли удалить Traceback через try except?

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

Закрепите навык на живых ошибках

Запускайте короткие задания в курсе Python и разбирайте каждое сообщение по одному маршруту: причина, строка, значения, вызовы. Если Python не видит библиотеку, откройте инструкцию про No module named.

Общий порядок поиска пригодится в статье 15 частых ошибок новичков. В Кодике можно сохранить минимальный пример и попросить Кодик GPT объяснить конкретный кадр, не переписывая за вас всю программу.