Traceback в Python – процесс, с которым может рано или поздно столкнуться любой разработчик. Соответствующий компонент необходимо грамотно считывать и обрабатывать. В противном случае от него не будет никакого толку, а исправить ситуацию станет практически невозможно. Связано это с тем, что traceback exception тесно связан с ошибками, возникающими при компиляции кода.

Несмотря на то, что изначально соответствующий элемент выглядит устрашающе (особенно для новичков), информация в нем будет крайне полезной при отладке программного обеспечения. Далее предстоит получше изучить упомянутый компонент, а также познакомиться с его исключениями. Предложенная информация будет полезна как новичкам, так и более опытным разработчика. Она больше ориентирована на тех, кто уже имеет хоть какой-то опыт в разработке на the Python 3.

Определение

The traceback exception – это трассировка. Она представляет собой отчет, который включает в себя информацию о вызовах выполненных функций программного кода в тот или иной момент. Появляется рассматриваемый элемент во время обнаружения ошибок реализации (компиляции) программы.

Трассировка описывается различными терминами. Примеры – трассировка стека или обратная трассировка. Далее будет использоваться понятие the traceback или просто «трассировка».

Каждый раз, когда Python выдает исключение или error, система выводит на экран специальное сообщение. Оно и будет является трассировкой. Данный отчет помогает понять, что пошло не так. Ниже можно увидеть наглядный пример рассматриваемого элемента.

Traceback в Питоне

В заданном примере:

  1. Происходит вызов функции greet. У нее есть параметр – someone.
  2. В greet это имя переменной не используется.
  3. Вместо соответствующего действия переменная someone указана при вызове функции на печать в print.

Описанная ситуация приведет к появлению ошибки. После обработки представленного фрагмента исходного кода на дисплее появится такой отчет:

Traceback в Питоне

Здесь содержится вся информация, которая поможет при диагностике error. Последняя строка вывода указывает на то, какой тип исключения генерировался вместе с некоторыми данными об исключении. Предыдущие строчки описывают причину генерации exception.

В предложенном the stacktrace в виде исключения выступает NameError. Это значит, что есть ссылка на какое-то имя (переменная, класс или функциям), которое не удалось определить. Здесь это – someone.

Последняя строчка в сложившейся ситуации располагает достаточной информацией о том, чтобы помочь разработчику исправить ситуацию. Поиск кода через имя someone, который выступает орфографической ошибкой, укажет на правильное дальнейшее «движение». Это элементарный случай, но на практике обычно code сложнее. И трассировку приходится грамотно считывать.

Правила чтения traceback

Traceback – это отчет, который необходимо грамотно считывать, чтобы понять причину ошибки, которая возникла in the code. Далее предстоит более детально изучить разнообразие виды the stacktrace, которые помогут лучше осознать разницу между имеющейся в «документации» информации.

Существуют различные секции для каждой трассировки. Такое разделение является крайне важным моментом. Вот диаграмма the stack trace, которая описывает несколько областей отчета:

Traceback в Питоне

Отличительной чертой traceback в Питоне является порядок чтения. Чтобы лучше и быстрее разобраться с предложенными данными, «документация» должна считываться в направлении «снизу–вверх».

Здесь:

  1. Синяя область – это последняя строка из the traceback. Она указывает на уведомление об ошибке (error). Синий фрагмент – это непосредственное названия возникшего в процессе обработки code сбоя.
  2. Зеленая область, которая указана после ошибки в the traceback exception – непосредственное описание. В соответствующем блоке прописываются сведения, которые помогают разобраться в истинных причинах возникновения сбоя.
  3. Желтая область – блок, в котором описаны разнообразные вызовы функций. Записи ведутся в направлении «снизу–вверх» от самых последних до самых первых. Эти вызовы представляются двухстрочными вводами для каждой записи. Первая строчка в очередном вызове включает в себя данные в виде: названия файла, номер строки и название модуля (in module). Все это помогает выяснить, где может быть обнаружен код.
  4. Красное подчеркивание. Это – вторая строка соответствующих вызовов в Python traceback. Она включает в себя непосредственный код, в котором был обнаружен сбой.

Существует разница между выдачей трассировок, когда разработчик запускает код в командной строке, а также между import traceback в REPL. Ниже – наглядный пример уже рассмотренного раздела. Он активирован через REPL. Трассировка в этом случае будет выглядеть иначе:

Traceback в Питоне

В месте названия файла тут написано stdin. Выполненные строки в таком отчете не будут отображаться.

Стоит обратить внимание на то, что the stack trace в Питоне отличается от отчетов в других языках разработки. Ключевая разница заключается в том, что большинство ЯП предлагают вывод ошибки (the error) в самом начале. Далее в направлении «сверху–вниз» записывается необходимая информация от недавних до последних реализованных.

Наглядные примеры кодов

Чтобы лучше понимать import traceback, а также научиться считывать трассировку в том или ином случае, рекомендуется рассматривать отчеты на наглядных примерах. Только после этого предстоит познакомиться поближе с возможными исключениями.

Вот – код, который записан в файле greetings.py. Он будет использоваться для наглядного примера и подробного разбора появившейся отчетности:

Traceback в Питоне

Соответствующий фрагмент работает так:

  1. Функция who_to_greet будет принимать значение person. Она вернет или соответствующее значение (если оно не является пустым), или запросит информацию от пользовательского ввода.
  2. Для того, чтобы клиент мог вводить сведения в приложение, используется input.
  3. После этого greet будет брать имя для приветствия из someone, необязательный параметр из greeting.
  4. После этого система потребует сведения на вывод. Операция осуществляется посредством print.
  5. Вместе с переданным значением из someone будет вызвана функция who_to_greet.
  6. Теперь greet_many будет выполнять итерации по списку людей. Это приведет к вызову greet.
  7. Если при работе с greet возникает сбой (ошибка), выводится резервное приветствие. Оно выражается записью print («hi» + person).

Предложенный выше фрагмент кода является правильным. Ошибок он вызывать не должен. Если добавить вызов функции greet в конце исходного документа, а также передать аргумент, который является для системы неожиданным (пример – greet (“Chad”, greeting = “Хай”)), система выдаст ошибку. На экране появится the stack trace:

Traceback в Питоне

Предложенный отчет рекомендуется считывать снизу–вверх. В последней строчке the traces появляется ошибка Type Error. Все сообщения, идущие после типа сбоя, отображают важные для обработки сбоя сведения. Отчет указывает на то, что greet вызывался с аргументом, который не поддерживается (не ожидается) системой. Неизвестный параметр тоже отображается. В заданном примере – это greeting.

Если подняться по «коду» чуть выше, можно увидеть строчку, в котором появилось исключение. Ей выступает greet, которая была добавлена в самом конце greetings.py.

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

Пример 2

А вот еще один вариант работы с traceback. В нем в качестве «основы» будет использоваться ранее рассмотренный фрагмент. В нем удаляется greet в самом конце. Вместе этого необходимо добавить файл под названием example.py в папку:

Traceback в Питоне

Тут происходит настройка еще одного Python-файла. Он требуется для импорта предыдущего модуля greetings.py. Далее разработчик будет использовать соответствующий «новый» документ в функции greet. Если запустить example.py, произойдет следующее:

Traceback в Питоне

В этом Python traceback:

  1. Снова возникает ошибка TypeError.
  2. На этот раз в отчетности можно увидеть сообщение, которое будет не слишком полезно разработчику. Это значит, что где-то в программном коде ожидается работа со строкой, но было передано целое число.
  3. Если подняться чуть выше, программист увидит фрагмент, который будет обработан системой. Далее указывается файл и номер кодовой строчки.
  4. Здесь разработчик получил имя функции greet. Она была успешно выполнена в процессе очередной итерации.
  5. Еще выше в the traceback можно увидеть «проблемный» вызов greet. Он передает целочисленное значение, что впоследствии приводит к сбою.

Python exception-traceback после появления ошибки может взять другой блок кода и вывести его в отчетности. При подобных обстоятельствах Питон выведет все трассировки ошибки в том порядке, в котором они были получены. За счет подобной особенности разработчики сумеют отследить, где именно начался сбой. В traceback заканчиваться документация будет самой последней трассировкой.

Пример 3 – как не запутаться в отчетах

Чтобы лучше разобраться в последней описанной ситуации, разработчикам рекомендуется изучить наглядный пример. В качестве базового кода будет использоваться уже известный по предыдущим кодам и отчетностям. В самом конце greetings.py рекомендуется добавить вызов greet_many:

Traceback в Питоне

Соответствующая ситуация приводит к выводу приветствия для трех человек. Если запустить получившийся в конечном итоге, на выходе получатся сразу несколько трассировок (python print traceback):

Traceback в Питоне

Стоит обратить внимание на выделенную строку, которая начинается с «During handling…». Она используется для того, чтобы разделять the stacktraces. Подобная запись сигнализирует о том, что при попытке обработать предыдущий сбой, появилась новая ошибка.

Еще один момент – это возможность отображения предыдущих трассировок. Подобная функциональность появилась не сразу. Ее разработчики Python добавили в 3 версии. В более ранних сборках языка на экране будет выводиться только последняя ошибка.

Предыдущая ошибка могла быть замечена разработчиком при вызове greet() с целочисленным параметром. При добавлении 1 в список людей для приветствия, ожидается точно такой же результат. Только функция greet_many оборачивает вызов greet. После этого она пытается работать в блоках try и an except. Если greet приведет в ошибке, greet_many выведет приветствие по умолчанию.

Тут повторяется соответствующая часть greetings.py:

Traceback в Питоне

Здесь:

  1. Когда greet приведет к TypeError traceback из-за неправильного ввода числа, greet_many обработает возникший сбой.
  2. Результатом выполненных операций станет попытка вывода простого приветствия.
  3. Это повлечет за собой новый сбой. Система все еще пытается добавить строчку и целое число.

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

Основные traceback исключения

Ускорить процесс понимания the traceback поможет более детальное изучение исключений. Навыки различать разнообразные трассировки значительно упрощают процедуру отладки программного обеспечения. Далее представлены the exception traceback, которые встречаются в разработке чаще всего.

AttributeError

The AttributeError появляется тогда, когда программист пытается получить доступ к атрибуту объекта (object), который не имеет конкретного атрибута. В официальной документации языка говорится о том, что она возникает при вызове несуществующего атрибута или при присвоении значения несуществующему атрибуту.

Вот – наглядный пример такой ошибки:

Traceback в Питоне

В строке уведомления о произошедшем AttributeError указано о том, что определенных тип объекта (int) не имеет доступа к атрибуту (an_attribute). За счет более детального изучения отчетности разработчик сможет быстро понять, куда пыталась перейти система, а также дальнейший алгоритм действия для устранения неполадок.

Traceback в Питоне

Рассматриваемый the exception traceback в основном указывает на то, что программист работает с объектом, тип которого не является ожидаемым. Эта ситуация наглядно продемонстрирована выше. Тут:

  1. Можно ожидать, что a_list будет являться типом списка, который включает в себя метод .append.
  2. При получении the AttributeError указывается, что сбой произошел в упомянутом ранее методе.
  3. Соответствующая ситуация указывает на то, что программист может иметь дело с типом объекта, который не ожидается системой.

Подобная ситуация возможно тогда, когда разработчик ожидает, что объект вернется из вызова функции или метода, а также будет относиться к определенному типу, но «на выходе» получается тип объекта None. В соответствующем случае the traceback будет выглядеть так:

Traceback в Питоне

Это – не единственное исключение, которое может быть вызвано системой. Разработчики могут сталкиваться и с другими сбоями.

ImportError

The ImportError – это сигнализация о том, что что-то не так с оператором import. Traceback exception или ее подкласс, который называется ModuleNotFoundError возникает тогда, когда модуль, который импортируется, не может быть обнаружен. Аналогично ситуация обстоит с импортом того, что не существует в системе. В документации указано следующее:

Traceback в Питоне

Выглядят The ImportError и ModuleNotFountError так:

Traceback в Питоне

Заданный пример показывает, что попытка импорта модуля asdf, которого не существует, приводит к образованию the ModuleNotFound. Если же попытаться импортировать то, что не существует (в соответствующем случае – asdf) из модуля, которого нет (collections), произойдет сбой типа ImportError. Строки сообщения о the traceback error in Python указывают на то, что именно не может быть импортировано. В приведенной ситуации в обоих случаях это asdf.

IndexError

The IndexError Traceback выводится тогда, когда разработчик пытается вернуть индекс из имеющейся последовательности (списка, кортежа), но соответствующий компонент не может быть обнаружен. В документации указывается следующее:

Traceback в Питоне

А вот пример, обработка которого приведет к IndexError:

Traceback в Питоне

Здесь:

  1. Строка сообщения об ошибке IndexError не дает полноценную информацию.
  2. Разработчик может увидеть, что имеется отсылка к последовательности, которая не доступна.
  3. Дополнительно отображаются сведения о том, какой тип последовательностей используется в приложении. В рассматриваемом примере им является список.

Простыми словами: в списке a_list нет значения с ключом 3. Поддерживаются только параметры с ключами 0 и 1, что значит a и b соответственно.

Рассматривать IndexError рекомендуется вместе с остальными трассировками. Лишь в этом случае удается полноценно отследить источник проблемы и оперативно устранить его.

KeyError

Возникает KeyError в тех же ситуациях, что и в случае с the IndexError – когда разработчик пытается получить доступ к ключу, который отсутствует в отображении. Обычно это dict (словарь). KeyError может рассматриваться как IndexError для словарей в программном коде. Вот так выглядит высказывание о трассировке для словарей:

Traceback в Питоне

Наглядный пример the KeyError traceback:

Traceback в Питоне

В строке уведомления KeyError говорится о ключе, который не может быть обнаружен системой. Этого мало для исправления ситуации, поэтому предстоит изучить остальную часть трассировки для отладки программного кода.

NameError

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

Traceback в Питоне

А вот – код, в котором greet будет брать в качестве параметра person. В задействованной функции соответствующее значение описано как person. Это ошибка, которая приведет к трассировке:

Traceback в Питоне

Строка уведомления об ошибке traceback NameError указывает на непосредственное название искомой функции. Приведенный пример вызывает его с ошибкой.

NameError также может выскакивать, если разработчик неправильно называет параметр:

Traceback в Питоне

В этом примере все кажется так, словно разработчик написал правильный и грамотный код. Последняя строка, которая была обработана (на нее же ссылается трассировка) выглядит хорошо.

В подобном случае рекомендуется внимательно изучить исходный код приложения. Необходимо найти участок, где переменная person определялась и использовалась. За счет этого получится увидеть, что название параметра введено с ошибкой.

SyntaxError

Возникает, когда синтаксический анализатор обнаруживает ошибку. Указывает на то, что разработчик неправильно написал код. Принципы, предусматриваемые синтаксисом Python, не соблюдены.

Вот – пример, где import traceback заключается в отсутствии двоеточия. Оно должно быть расположено в конце строки определения функции. В REPL подобная ситуация возникнет сразу после того, как программист нажмет на Enter:

Traceback в Питоне

В строке уведомления будет указано только о том, что имеется проблема синтаксического характера. Обычно информация, написанная над SyntaxError, помогает выяснить причину происходящего. Каретка ^ часто сигнализирует о «проблемной» области. В приведенном примере – это отсутствие двоеточия в операторе def заданной функции.

В случае с трассировками типа SyntaxError, привычная первая строка the import-traceback будет отсутствовать. Ситуация складывается из-за того, что SyntaxError возникает в момент, когда Python пытается парсить исходный код. Фактически строки выполняться не будут.

TypeError

The TypeError появляется тогда, когда программный код пытается выполнить действия с объектом, который не может этого сделать. Пример – попытка добавления строки в целое число или вызов len для объекта, в котором отсутствует определение длины.

Traceback в Питоне
Traceback в Питоне

Выше можно увидеть сразу несколько примеров TypeError. В строке уведомления будет появляться различная информация. Каждый такой компонент предоставляет достаточную информацию о том, что пошло не так.

Первые два примера – это ввод строк и целых чисел совместно:

  • первый пример – попытка добавить str K int;
  • второй пример – добавление int K str.

На соответствующие различия ссылаются предоставленные уведомления. В последнем примере разработчик пытается вызвать len для int. С целочисленными значениями подобная операция невозможна. Из-за этого возникает исключение TypeError.

ValueError

ValueError выскакивает тогда, когда значения объектов не являются корректными. Соответствующее исключение может рассматриваться в качестве IndexError, которая возникает ввиду расположения индекса вне используемого диапазона. ValueError traceback служит более обобщенным случаем.

Traceback в Питоне
Traceback в Питоне

В строке уведомления ValueError в приведенных выше примерах точно указано, где кроется проблема:

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

Все перечисленные исключения – это самые распространенные в Python. Они не являются исчерпывающими, но встречаются в разработке программного обеспечения чаще остальных.

Лучше разобраться с import traceback, а также рассмотреть другие ошибки при трассировке, помогут дистанционные онлайн-курсы. Они рассчитаны на широкую публику и могут быть подобраны в зависимости от первоначальных знаний разработчика. В срок до 12 месяцев пользователь сможет освоить любое IT-направление и подтвердить обучение электронным сертификатом.

Интересует Python? Добро пожаловать на курс в Otus!