Traceback в Python – процесс, с которым может рано или поздно столкнуться любой разработчик. Соответствующий компонент необходимо грамотно считывать и обрабатывать. В противном случае от него не будет никакого толку, а исправить ситуацию станет практически невозможно. Связано это с тем, что traceback exception тесно связан с ошибками, возникающими при компиляции кода.
Несмотря на то, что изначально соответствующий элемент выглядит устрашающе (особенно для новичков), информация в нем будет крайне полезной при отладке программного обеспечения. Далее предстоит получше изучить упомянутый компонент, а также познакомиться с его исключениями. Предложенная информация будет полезна как новичкам, так и более опытным разработчика. Она больше ориентирована на тех, кто уже имеет хоть какой-то опыт в разработке на the Python 3.
Определение
The traceback exception – это трассировка. Она представляет собой отчет, который включает в себя информацию о вызовах выполненных функций программного кода в тот или иной момент. Появляется рассматриваемый элемент во время обнаружения ошибок реализации (компиляции) программы.
Трассировка описывается различными терминами. Примеры – трассировка стека или обратная трассировка. Далее будет использоваться понятие the traceback или просто «трассировка».
Каждый раз, когда Python выдает исключение или error, система выводит на экран специальное сообщение. Оно и будет является трассировкой. Данный отчет помогает понять, что пошло не так. Ниже можно увидеть наглядный пример рассматриваемого элемента.
В заданном примере:
- Происходит вызов функции greet. У нее есть параметр – someone.
- В greet это имя переменной не используется.
- Вместо соответствующего действия переменная someone указана при вызове функции на печать в print.
Описанная ситуация приведет к появлению ошибки. После обработки представленного фрагмента исходного кода на дисплее появится такой отчет:
Здесь содержится вся информация, которая поможет при диагностике error. Последняя строка вывода указывает на то, какой тип исключения генерировался вместе с некоторыми данными об исключении. Предыдущие строчки описывают причину генерации exception.
В предложенном the stacktrace в виде исключения выступает NameError. Это значит, что есть ссылка на какое-то имя (переменная, класс или функциям), которое не удалось определить. Здесь это – someone.
Последняя строчка в сложившейся ситуации располагает достаточной информацией о том, чтобы помочь разработчику исправить ситуацию. Поиск кода через имя someone, который выступает орфографической ошибкой, укажет на правильное дальнейшее «движение». Это элементарный случай, но на практике обычно code сложнее. И трассировку приходится грамотно считывать.
Traceback – это отчет, который необходимо грамотно считывать, чтобы понять причину ошибки, которая возникла in the code. Далее предстоит более детально изучить разнообразие виды the stacktrace, которые помогут лучше осознать разницу между имеющейся в «документации» информации.
Существуют различные секции для каждой трассировки. Такое разделение является крайне важным моментом. Вот диаграмма the stack trace, которая описывает несколько областей отчета:
Отличительной чертой traceback в Питоне является порядок чтения. Чтобы лучше и быстрее разобраться с предложенными данными, «документация» должна считываться в направлении «снизу–вверх».
Здесь:
- Синяя область – это последняя строка из the traceback. Она указывает на уведомление об ошибке (error). Синий фрагмент – это непосредственное названия возникшего в процессе обработки code сбоя.
- Зеленая область, которая указана после ошибки в the traceback exception – непосредственное описание. В соответствующем блоке прописываются сведения, которые помогают разобраться в истинных причинах возникновения сбоя.
- Желтая область – блок, в котором описаны разнообразные вызовы функций. Записи ведутся в направлении «снизу–вверх» от самых последних до самых первых. Эти вызовы представляются двухстрочными вводами для каждой записи. Первая строчка в очередном вызове включает в себя данные в виде: названия файла, номер строки и название модуля (in module). Все это помогает выяснить, где может быть обнаружен код.
- Красное подчеркивание. Это – вторая строка соответствующих вызовов в Python traceback. Она включает в себя непосредственный код, в котором был обнаружен сбой.
Существует разница между выдачей трассировок, когда разработчик запускает код в командной строке, а также между import traceback в REPL. Ниже – наглядный пример уже рассмотренного раздела. Он активирован через REPL. Трассировка в этом случае будет выглядеть иначе:
В месте названия файла тут написано stdin. Выполненные строки в таком отчете не будут отображаться.
Стоит обратить внимание на то, что the stack trace в Питоне отличается от отчетов в других языках разработки. Ключевая разница заключается в том, что большинство ЯП предлагают вывод ошибки (the error) в самом начале. Далее в направлении «сверху–вниз» записывается необходимая информация от недавних до последних реализованных.
Наглядные примеры кодов
Чтобы лучше понимать import traceback, а также научиться считывать трассировку в том или ином случае, рекомендуется рассматривать отчеты на наглядных примерах. Только после этого предстоит познакомиться поближе с возможными исключениями.
Вот – код, который записан в файле greetings.py. Он будет использоваться для наглядного примера и подробного разбора появившейся отчетности:
Соответствующий фрагмент работает так:
- Функция who_to_greet будет принимать значение person. Она вернет или соответствующее значение (если оно не является пустым), или запросит информацию от пользовательского ввода.
- Для того, чтобы клиент мог вводить сведения в приложение, используется input.
- После этого greet будет брать имя для приветствия из someone, необязательный параметр из greeting.
- После этого система потребует сведения на вывод. Операция осуществляется посредством print.
- Вместе с переданным значением из someone будет вызвана функция who_to_greet.
- Теперь greet_many будет выполнять итерации по списку людей. Это приведет к вызову greet.
- Если при работе с greet возникает сбой (ошибка), выводится резервное приветствие. Оно выражается записью print («hi» + person).
Предложенный выше фрагмент кода является правильным. Ошибок он вызывать не должен. Если добавить вызов функции greet в конце исходного документа, а также передать аргумент, который является для системы неожиданным (пример – greet (“Chad”, greeting = “Хай”)), система выдаст ошибку. На экране появится the stack trace:
Предложенный отчет рекомендуется считывать снизу–вверх. В последней строчке the traces появляется ошибка Type Error. Все сообщения, идущие после типа сбоя, отображают важные для обработки сбоя сведения. Отчет указывает на то, что greet вызывался с аргументом, который не поддерживается (не ожидается) системой. Неизвестный параметр тоже отображается. В заданном примере – это greeting.
Если подняться по «коду» чуть выше, можно увидеть строчку, в котором появилось исключение. Ей выступает greet, которая была добавлена в самом конце greetings.py.
Далее отображается строка, указывающая на путь к файлу, в котором находится код, номер строки соответствующего файла, где именно расположен код, а также информацию о его модуле. В предложенном фрагменте никаких модулей нет, поэтому в необходимых строчках будет отображена информация о том, что файл является исполняемым.
Пример 2
А вот еще один вариант работы с traceback. В нем в качестве «основы» будет использоваться ранее рассмотренный фрагмент. В нем удаляется greet в самом конце. Вместе этого необходимо добавить файл под названием example.py в папку:
Тут происходит настройка еще одного Python-файла. Он требуется для импорта предыдущего модуля greetings.py. Далее разработчик будет использовать соответствующий «новый» документ в функции greet. Если запустить example.py, произойдет следующее:
В этом Python traceback:
- Снова возникает ошибка TypeError.
- На этот раз в отчетности можно увидеть сообщение, которое будет не слишком полезно разработчику. Это значит, что где-то в программном коде ожидается работа со строкой, но было передано целое число.
- Если подняться чуть выше, программист увидит фрагмент, который будет обработан системой. Далее указывается файл и номер кодовой строчки.
- Здесь разработчик получил имя функции greet. Она была успешно выполнена в процессе очередной итерации.
- Еще выше в the traceback можно увидеть «проблемный» вызов greet. Он передает целочисленное значение, что впоследствии приводит к сбою.
Python exception-traceback после появления ошибки может взять другой блок кода и вывести его в отчетности. При подобных обстоятельствах Питон выведет все трассировки ошибки в том порядке, в котором они были получены. За счет подобной особенности разработчики сумеют отследить, где именно начался сбой. В traceback заканчиваться документация будет самой последней трассировкой.
Пример 3 – как не запутаться в отчетах
Чтобы лучше разобраться в последней описанной ситуации, разработчикам рекомендуется изучить наглядный пример. В качестве базового кода будет использоваться уже известный по предыдущим кодам и отчетностям. В самом конце greetings.py рекомендуется добавить вызов greet_many:
Соответствующая ситуация приводит к выводу приветствия для трех человек. Если запустить получившийся в конечном итоге, на выходе получатся сразу несколько трассировок (python print traceback):
Стоит обратить внимание на выделенную строку, которая начинается с «During handling…». Она используется для того, чтобы разделять the stacktraces. Подобная запись сигнализирует о том, что при попытке обработать предыдущий сбой, появилась новая ошибка.
Еще один момент – это возможность отображения предыдущих трассировок. Подобная функциональность появилась не сразу. Ее разработчики Python добавили в 3 версии. В более ранних сборках языка на экране будет выводиться только последняя ошибка.
Предыдущая ошибка могла быть замечена разработчиком при вызове greet() с целочисленным параметром. При добавлении 1 в список людей для приветствия, ожидается точно такой же результат. Только функция greet_many оборачивает вызов greet. После этого она пытается работать в блоках try и an except. Если greet приведет в ошибке, greet_many выведет приветствие по умолчанию.
Тут повторяется соответствующая часть greetings.py:
Здесь:
- Когда greet приведет к TypeError traceback из-за неправильного ввода числа, greet_many обработает возникший сбой.
- Результатом выполненных операций станет попытка вывода простого приветствия.
- Это повлечет за собой новый сбой. Система все еще пытается добавить строчку и целое число.
Если внимательно просмотреть весь traceback, можно заметить, что именно послужило причиной ошибок. Бывают ситуации, при которых программист получает только последний сбой с последующей traceback. В этом случае проблематично отследить, где и что пошло не по плану. Исправить положение удастся за счет рассмотрения предыдущих ошибок и сбоев.
Основные traceback исключения
Ускорить процесс понимания the traceback поможет более детальное изучение исключений. Навыки различать разнообразные трассировки значительно упрощают процедуру отладки программного обеспечения. Далее представлены the exception traceback, которые встречаются в разработке чаще всего.
AttributeError
The AttributeError появляется тогда, когда программист пытается получить доступ к атрибуту объекта (object), который не имеет конкретного атрибута. В официальной документации языка говорится о том, что она возникает при вызове несуществующего атрибута или при присвоении значения несуществующему атрибуту.
Вот – наглядный пример такой ошибки:
В строке уведомления о произошедшем AttributeError указано о том, что определенных тип объекта (int) не имеет доступа к атрибуту (an_attribute). За счет более детального изучения отчетности разработчик сможет быстро понять, куда пыталась перейти система, а также дальнейший алгоритм действия для устранения неполадок.
Рассматриваемый the exception traceback в основном указывает на то, что программист работает с объектом, тип которого не является ожидаемым. Эта ситуация наглядно продемонстрирована выше. Тут:
- Можно ожидать, что a_list будет являться типом списка, который включает в себя метод .append.
- При получении the AttributeError указывается, что сбой произошел в упомянутом ранее методе.
- Соответствующая ситуация указывает на то, что программист может иметь дело с типом объекта, который не ожидается системой.
Подобная ситуация возможно тогда, когда разработчик ожидает, что объект вернется из вызова функции или метода, а также будет относиться к определенному типу, но «на выходе» получается тип объекта None. В соответствующем случае the traceback будет выглядеть так:
Это – не единственное исключение, которое может быть вызвано системой. Разработчики могут сталкиваться и с другими сбоями.
ImportError
The ImportError – это сигнализация о том, что что-то не так с оператором import. Traceback exception или ее подкласс, который называется ModuleNotFoundError возникает тогда, когда модуль, который импортируется, не может быть обнаружен. Аналогично ситуация обстоит с импортом того, что не существует в системе. В документации указано следующее:
Выглядят The ImportError и ModuleNotFountError так:
Заданный пример показывает, что попытка импорта модуля asdf, которого не существует, приводит к образованию the ModuleNotFound. Если же попытаться импортировать то, что не существует (в соответствующем случае – asdf) из модуля, которого нет (collections), произойдет сбой типа ImportError. Строки сообщения о the traceback error in Python указывают на то, что именно не может быть импортировано. В приведенной ситуации в обоих случаях это asdf.
IndexError
The IndexError Traceback выводится тогда, когда разработчик пытается вернуть индекс из имеющейся последовательности (списка, кортежа), но соответствующий компонент не может быть обнаружен. В документации указывается следующее:
А вот пример, обработка которого приведет к IndexError:
Здесь:
- Строка сообщения об ошибке IndexError не дает полноценную информацию.
- Разработчик может увидеть, что имеется отсылка к последовательности, которая не доступна.
- Дополнительно отображаются сведения о том, какой тип последовательностей используется в приложении. В рассматриваемом примере им является список.
Простыми словами: в списке a_list нет значения с ключом 3. Поддерживаются только параметры с ключами 0 и 1, что значит a и b соответственно.
Рассматривать IndexError рекомендуется вместе с остальными трассировками. Лишь в этом случае удается полноценно отследить источник проблемы и оперативно устранить его.
KeyError
Возникает KeyError в тех же ситуациях, что и в случае с the IndexError – когда разработчик пытается получить доступ к ключу, который отсутствует в отображении. Обычно это dict (словарь). KeyError может рассматриваться как IndexError для словарей в программном коде. Вот так выглядит высказывание о трассировке для словарей:
Наглядный пример the KeyError traceback:
В строке уведомления KeyError говорится о ключе, который не может быть обнаружен системой. Этого мало для исправления ситуации, поэтому предстоит изучить остальную часть трассировки для отладки программного кода.
NameError
Сбой, который отображается, если разработчик ссылается на название модуля, переменной, функции, класса или иного компонента, имя которой не определено в коде. В официальной документации the Python указано следующее:
А вот – код, в котором greet будет брать в качестве параметра person. В задействованной функции соответствующее значение описано как person. Это ошибка, которая приведет к трассировке:
Строка уведомления об ошибке traceback NameError указывает на непосредственное название искомой функции. Приведенный пример вызывает его с ошибкой.
NameError также может выскакивать, если разработчик неправильно называет параметр:
В этом примере все кажется так, словно разработчик написал правильный и грамотный код. Последняя строка, которая была обработана (на нее же ссылается трассировка) выглядит хорошо.
В подобном случае рекомендуется внимательно изучить исходный код приложения. Необходимо найти участок, где переменная person определялась и использовалась. За счет этого получится увидеть, что название параметра введено с ошибкой.
SyntaxError
Возникает, когда синтаксический анализатор обнаруживает ошибку. Указывает на то, что разработчик неправильно написал код. Принципы, предусматриваемые синтаксисом Python, не соблюдены.
Вот – пример, где import traceback заключается в отсутствии двоеточия. Оно должно быть расположено в конце строки определения функции. В REPL подобная ситуация возникнет сразу после того, как программист нажмет на Enter:
В строке уведомления будет указано только о том, что имеется проблема синтаксического характера. Обычно информация, написанная над SyntaxError, помогает выяснить причину происходящего. Каретка ^ часто сигнализирует о «проблемной» области. В приведенном примере – это отсутствие двоеточия в операторе def заданной функции.
В случае с трассировками типа SyntaxError, привычная первая строка the import-traceback будет отсутствовать. Ситуация складывается из-за того, что SyntaxError возникает в момент, когда Python пытается парсить исходный код. Фактически строки выполняться не будут.
TypeError
The TypeError появляется тогда, когда программный код пытается выполнить действия с объектом, который не может этого сделать. Пример – попытка добавления строки в целое число или вызов len для объекта, в котором отсутствует определение длины.
Выше можно увидеть сразу несколько примеров TypeError. В строке уведомления будет появляться различная информация. Каждый такой компонент предоставляет достаточную информацию о том, что пошло не так.
Первые два примера – это ввод строк и целых чисел совместно:
- первый пример – попытка добавить str K int;
- второй пример – добавление int K str.
На соответствующие различия ссылаются предоставленные уведомления. В последнем примере разработчик пытается вызвать len для int. С целочисленными значениями подобная операция невозможна. Из-за этого возникает исключение TypeError.
ValueError
ValueError выскакивает тогда, когда значения объектов не являются корректными. Соответствующее исключение может рассматриваться в качестве IndexError, которая возникает ввиду расположения индекса вне используемого диапазона. ValueError traceback служит более обобщенным случаем.
В строке уведомления ValueError в приведенных выше примерах точно указано, где кроется проблема:
- Первый пример предусматривает попытку распаковки слишком большого количества значений. В строке уведомлений говорится о том, где именно ожидается распаковка трех значений, но на выходе получаются только два.
- Во втором примере программа пытается получить слишком много значений. Для распаковки их недостаточно.
Все перечисленные исключения – это самые распространенные в Python. Они не являются исчерпывающими, но встречаются в разработке программного обеспечения чаще остальных.
Лучше разобраться с import traceback, а также рассмотреть другие ошибки при трассировке, помогут дистанционные онлайн-курсы. Они рассчитаны на широкую публику и могут быть подобраны в зависимости от первоначальных знаний разработчика. В срок до 12 месяцев пользователь сможет освоить любое IT-направление и подтвердить обучение электронным сертификатом.
Интересует Python? Добро пожаловать на курс в Otus!
<!DOCTYPE html>
<html dir="ltr" lang="ru-RU">
<head>
<meta charset="UTF-8" />
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="profile" href="http://gmpg.org/xfn/11" />
<title>Traceback в Питоне OTUS</title>
<!-- All in One SEO 4.5.2.1 - aioseo.com -->
<meta name="description" content="Traceback в Python – процесс, с которым может рано или поздно столкнуться любой разработчик. Соответствующий компонент необходимо грамотно считывать и обрабатывать. В противном случае от него не будет никакого толку, а исправить ситуацию станет практически невозможно. Связано это с тем, что traceback exception тесно связан с ошибками, возникающими при компиляции кода. Несмотря на то, что" />
<meta name="robots" content="max-image-preview:large" />
<link rel="canonical" href="https://otus.ru/journal/traceback-v-pitone/" />
<meta name="generator" content="All in One SEO (AIOSEO) 4.5.2.1" />
<script type="application/ld+json" class="aioseo-schema">
{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/otus.ru\/journal\/traceback-v-pitone\/#article","name":"Traceback \u0432 \u041f\u0438\u0442\u043e\u043d\u0435 OTUS","headline":"Traceback \u0432 \u041f\u0438\u0442\u043e\u043d\u0435","author":{"@id":"https:\/\/otus.ru\/journal\/author\/a-pavlenko\/#author"},"publisher":{"@id":"https:\/\/otus.ru\/journal\/#organization"},"image":{"@type":"ImageObject","url":"https:\/\/otus.ru\/journal\/wp-content\/uploads\/2023\/06\/oj-1080x72057-1.jpg","width":2245,"height":1587},"datePublished":"2023-06-06T15:49:38+00:00","dateModified":"2024-01-18T18:54:04+00:00","inLanguage":"ru-RU","mainEntityOfPage":{"@id":"https:\/\/otus.ru\/journal\/traceback-v-pitone\/#webpage"},"isPartOf":{"@id":"https:\/\/otus.ru\/journal\/traceback-v-pitone\/#webpage"},"articleSection":"\u041f\u043e\u043b\u0435\u0437\u043d\u043e\u0435, Python"},{"@type":"BreadcrumbList","@id":"https:\/\/otus.ru\/journal\/traceback-v-pitone\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/otus.ru\/journal\/#listItem","position":1,"name":"\u0413\u043b\u0430\u0432\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430","item":"https:\/\/otus.ru\/journal\/","nextItem":"https:\/\/otus.ru\/journal\/traceback-v-pitone\/#listItem"},{"@type":"ListItem","@id":"https:\/\/otus.ru\/journal\/traceback-v-pitone\/#listItem","position":2,"name":"Traceback \u0432 \u041f\u0438\u0442\u043e\u043d\u0435","previousItem":"https:\/\/otus.ru\/journal\/#listItem"}]},{"@type":"Organization","@id":"https:\/\/otus.ru\/journal\/#organization","name":"\u041e\u0442\u0443\u0441 \u043e\u043d\u043b\u0430\u0439\u043d-\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435","url":"https:\/\/otus.ru\/journal\/","sameAs":["https:\/\/www.youtube.com\/channel\/UCetgtvy93o3i3CvyGXKFU3g"],"contactPoint":{"@type":"ContactPoint","telephone":"+74999389202","contactType":"Customer Support"}},{"@type":"Person","@id":"https:\/\/otus.ru\/journal\/author\/a-pavlenko\/#author","url":"https:\/\/otus.ru\/journal\/author\/a-pavlenko\/","name":"A. Pavlenko","image":{"@type":"ImageObject","@id":"https:\/\/otus.ru\/journal\/traceback-v-pitone\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/d4c499a104d7c2522fa41f89e6819499?s=96&d=mm&r=g","width":96,"height":96,"caption":"A. Pavlenko"}},{"@type":"WebPage","@id":"https:\/\/otus.ru\/journal\/traceback-v-pitone\/#webpage","url":"https:\/\/otus.ru\/journal\/traceback-v-pitone\/","name":"Traceback \u0432 \u041f\u0438\u0442\u043e\u043d\u0435 OTUS","description":"Traceback \u0432 Python \u2013 \u043f\u0440\u043e\u0446\u0435\u0441\u0441, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043c\u043e\u0436\u0435\u0442 \u0440\u0430\u043d\u043e \u0438\u043b\u0438 \u043f\u043e\u0437\u0434\u043d\u043e \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u0442\u044c\u0441\u044f \u043b\u044e\u0431\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a. \u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0433\u0440\u0430\u043c\u043e\u0442\u043d\u043e \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0438 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c. \u0412 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0442 \u043d\u0435\u0433\u043e \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043d\u0438\u043a\u0430\u043a\u043e\u0433\u043e \u0442\u043e\u043b\u043a\u0443, \u0430 \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044e \u0441\u0442\u0430\u043d\u0435\u0442 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e. \u0421\u0432\u044f\u0437\u0430\u043d\u043e \u044d\u0442\u043e \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e traceback exception \u0442\u0435\u0441\u043d\u043e \u0441\u0432\u044f\u0437\u0430\u043d \u0441 \u043e\u0448\u0438\u0431\u043a\u0430\u043c\u0438, \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0449\u0438\u043c\u0438 \u043f\u0440\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u043a\u043e\u0434\u0430. \u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e","inLanguage":"ru-RU","isPartOf":{"@id":"https:\/\/otus.ru\/journal\/#website"},"breadcrumb":{"@id":"https:\/\/otus.ru\/journal\/traceback-v-pitone\/#breadcrumblist"},"author":{"@id":"https:\/\/otus.ru\/journal\/author\/a-pavlenko\/#author"},"creator":{"@id":"https:\/\/otus.ru\/journal\/author\/a-pavlenko\/#author"},"image":{"@type":"ImageObject","url":"https:\/\/otus.ru\/journal\/wp-content\/uploads\/2023\/06\/oj-1080x72057-1.jpg","@id":"https:\/\/otus.ru\/journal\/traceback-v-pitone\/#mainImage","width":2245,"height":1587},"primaryImageOfPage":{"@id":"https:\/\/otus.ru\/journal\/traceback-v-pitone\/#mainImage"},"datePublished":"2023-06-06T15:49:38+00:00","dateModified":"2024-01-18T18:54:04+00:00"},{"@type":"WebSite","@id":"https:\/\/otus.ru\/journal\/#website","url":"https:\/\/otus.ru\/journal\/","name":"OTUS JOURNAL","description":"Blog about IT","inLanguage":"ru-RU","publisher":{"@id":"https:\/\/otus.ru\/journal\/#organization"}}]}
</script>
<!-- All in One SEO -->
<link rel='dns-prefetch' href='//otus.ru' />
<link rel='dns-prefetch' href='//fonts.googleapis.com' />
<link rel='stylesheet' id='wp-block-library-css' href='https://otus.ru/journal/wp-includes/css/dist/block-library/style.min.css?ver=6.4.7' type='text/css' media='all' />
<style id='classic-theme-styles-inline-css' type='text/css'>
/*! This file is auto-generated */
.wp-block-button__link{color:#fff;background-color:#32373c;border-radius:9999px;box-shadow:none;text-decoration:none;padding:calc(.667em + 2px) calc(1.333em + 2px);font-size:1.125em}.wp-block-file__button{background:#32373c;color:#fff;text-decoration:none}
</style>
<style id='global-styles-inline-css' type='text/css'>
body{--wp--preset--color--black: #000000;--wp--preset--color--cyan-bluish-gray: #abb8c3;--wp--preset--color--white: #ffffff;--wp--preset--color--pale-pink: #f78da7;--wp--preset--color--vivid-red: #cf2e2e;--wp--preset--color--luminous-vivid-orange: #ff6900;--wp--preset--color--luminous-vivid-amber: #fcb900;--wp--preset--color--light-green-cyan: #7bdcb5;--wp--preset--color--vivid-green-cyan: #00d084;--wp--preset--color--pale-cyan-blue: #8ed1fc;--wp--preset--color--vivid-cyan-blue: #0693e3;--wp--preset--color--vivid-purple: #9b51e0;--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple: linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%);--wp--preset--gradient--light-green-cyan-to-vivid-green-cyan: linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%);--wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange: linear-gradient(135deg,rgba(252,185,0,1) 0%,rgba(255,105,0,1) 100%);--wp--preset--gradient--luminous-vivid-orange-to-vivid-red: linear-gradient(135deg,rgba(255,105,0,1) 0%,rgb(207,46,46) 100%);--wp--preset--gradient--very-light-gray-to-cyan-bluish-gray: linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%);--wp--preset--gradient--cool-to-warm-spectrum: linear-gradient(135deg,rgb(74,234,220) 0%,rgb(151,120,209) 20%,rgb(207,42,186) 40%,rgb(238,44,130) 60%,rgb(251,105,98) 80%,rgb(254,248,76) 100%);--wp--preset--gradient--blush-light-purple: linear-gradient(135deg,rgb(255,206,236) 0%,rgb(152,150,240) 100%);--wp--preset--gradient--blush-bordeaux: linear-gradient(135deg,rgb(254,205,165) 0%,rgb(254,45,45) 50%,rgb(107,0,62) 100%);--wp--preset--gradient--luminous-dusk: linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%);--wp--preset--gradient--pale-ocean: linear-gradient(135deg,rgb(255,245,203) 0%,rgb(182,227,212) 50%,rgb(51,167,181) 100%);--wp--preset--gradient--electric-grass: linear-gradient(135deg,rgb(202,248,128) 0%,rgb(113,206,126) 100%);--wp--preset--gradient--midnight: linear-gradient(135deg,rgb(2,3,129) 0%,rgb(40,116,252) 100%);--wp--preset--font-size--small: 13px;--wp--preset--font-size--medium: 20px;--wp--preset--font-size--large: 36px;--wp--preset--font-size--x-large: 42px;--wp--preset--spacing--20: 0.44rem;--wp--preset--spacing--30: 0.67rem;--wp--preset--spacing--40: 1rem;--wp--preset--spacing--50: 1.5rem;--wp--preset--spacing--60: 2.25rem;--wp--preset--spacing--70: 3.38rem;--wp--preset--spacing--80: 5.06rem;--wp--preset--shadow--natural: 6px 6px 9px rgba(0, 0, 0, 0.2);--wp--preset--shadow--deep: 12px 12px 50px rgba(0, 0, 0, 0.4);--wp--preset--shadow--sharp: 6px 6px 0px rgba(0, 0, 0, 0.2);--wp--preset--shadow--outlined: 6px 6px 0px -3px rgba(255, 255, 255, 1), 6px 6px rgba(0, 0, 0, 1);--wp--preset--shadow--crisp: 6px 6px 0px rgba(0, 0, 0, 1);}:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}:where(.wp-block-columns.is-layout-flex){gap: 2em;}:where(.wp-block-columns.is-layout-grid){gap: 2em;}:where(.wp-block-post-template.is-layout-flex){gap: 1.25em;}:where(.wp-block-post-template.is-layout-grid){gap: 1.25em;}.has-black-color{color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-color{color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-color{color: var(--wp--preset--color--white) !important;}.has-pale-pink-color{color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-color{color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-color{color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-color{color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-color{color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-color{color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-color{color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-color{color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-color{color: var(--wp--preset--color--vivid-purple) !important;}.has-black-background-color{background-color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-background-color{background-color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-background-color{background-color: var(--wp--preset--color--white) !important;}.has-pale-pink-background-color{background-color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-background-color{background-color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-background-color{background-color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-background-color{background-color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-background-color{background-color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-background-color{background-color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-background-color{background-color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-background-color{background-color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-background-color{background-color: var(--wp--preset--color--vivid-purple) !important;}.has-black-border-color{border-color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-border-color{border-color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-border-color{border-color: var(--wp--preset--color--white) !important;}.has-pale-pink-border-color{border-color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-border-color{border-color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-border-color{border-color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-border-color{border-color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-border-color{border-color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-border-color{border-color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-border-color{border-color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-border-color{border-color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-border-color{border-color: var(--wp--preset--color--vivid-purple) !important;}.has-vivid-cyan-blue-to-vivid-purple-gradient-background{background: var(--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple) !important;}.has-light-green-cyan-to-vivid-green-cyan-gradient-background{background: var(--wp--preset--gradient--light-green-cyan-to-vivid-green-cyan) !important;}.has-luminous-vivid-amber-to-luminous-vivid-orange-gradient-background{background: var(--wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange) !important;}.has-luminous-vivid-orange-to-vivid-red-gradient-background{background: var(--wp--preset--gradient--luminous-vivid-orange-to-vivid-red) !important;}.has-very-light-gray-to-cyan-bluish-gray-gradient-background{background: var(--wp--preset--gradient--very-light-gray-to-cyan-bluish-gray) !important;}.has-cool-to-warm-spectrum-gradient-background{background: var(--wp--preset--gradient--cool-to-warm-spectrum) !important;}.has-blush-light-purple-gradient-background{background: var(--wp--preset--gradient--blush-light-purple) !important;}.has-blush-bordeaux-gradient-background{background: var(--wp--preset--gradient--blush-bordeaux) !important;}.has-luminous-dusk-gradient-background{background: var(--wp--preset--gradient--luminous-dusk) !important;}.has-pale-ocean-gradient-background{background: var(--wp--preset--gradient--pale-ocean) !important;}.has-electric-grass-gradient-background{background: var(--wp--preset--gradient--electric-grass) !important;}.has-midnight-gradient-background{background: var(--wp--preset--gradient--midnight) !important;}.has-small-font-size{font-size: var(--wp--preset--font-size--small) !important;}.has-medium-font-size{font-size: var(--wp--preset--font-size--medium) !important;}.has-large-font-size{font-size: var(--wp--preset--font-size--large) !important;}.has-x-large-font-size{font-size: var(--wp--preset--font-size--x-large) !important;}
.wp-block-navigation a:where(:not(.wp-element-button)){color: inherit;}
:where(.wp-block-post-template.is-layout-flex){gap: 1.25em;}:where(.wp-block-post-template.is-layout-grid){gap: 1.25em;}
:where(.wp-block-columns.is-layout-flex){gap: 2em;}:where(.wp-block-columns.is-layout-grid){gap: 2em;}
.wp-block-pullquote{font-size: 1.5em;line-height: 1.6;}
</style>
<link rel='stylesheet' id='wbcr-comments-plus-url-span-css' href='https://otus.ru/journal/wp-content/plugins/clearfy/components/comments-plus/assets/css/url-span.css?ver=2.2.0' type='text/css' media='all' />
<link rel='stylesheet' id='wpel-style-css' href='https://otus.ru/journal/wp-content/plugins/wp-external-links/public/css/wpel.css?ver=2.59' type='text/css' media='all' />
<link rel='stylesheet' id='ez-toc-css' href='https://otus.ru/journal/wp-content/plugins/easy-table-of-contents/assets/css/screen.min.css?ver=2.0.61' type='text/css' media='all' />
<style id='ez-toc-inline-css' type='text/css'>
div#ez-toc-container .ez-toc-title {font-size: 120%;}div#ez-toc-container .ez-toc-title {font-weight: 500;}div#ez-toc-container ul li {font-size: 95%;}div#ez-toc-container nav ul ul li {font-size: 90%;}
.ez-toc-container-direction {direction: ltr;}.ez-toc-counter ul{counter-reset: item ;}.ez-toc-counter nav ul li a::before {content: counters(item, ".", decimal) ". ";display: inline-block;counter-increment: item;flex-grow: 0;flex-shrink: 0;margin-right: .2em; float: left; }.ez-toc-widget-direction {direction: ltr;}.ez-toc-widget-container ul{counter-reset: item ;}.ez-toc-widget-container nav ul li a::before {content: counters(item, ".", decimal) ". ";display: inline-block;counter-increment: item;flex-grow: 0;flex-shrink: 0;margin-right: .2em; float: left; }
</style>
<link rel='stylesheet' id='contentberg-fonts-css' href='https://fonts.googleapis.com/css?family=Roboto%3A400%2C500%2C700%7CPT+Serif%3A400%2C400i%2C600%7CIBM+Plex+Serif%3A500' type='text/css' media='all' />
<link rel='stylesheet' id='contentberg-core-css' href='https://otus.ru/journal/wp-content/themes/contentberg/style.css?ver=1.8.3' type='text/css' media='all' />
<link rel='stylesheet' id='contentberg-lightbox-css' href='https://otus.ru/journal/wp-content/themes/contentberg/css/lightbox.css?ver=1.8.3' type='text/css' media='all' />
<link rel='stylesheet' id='font-awesome-css' href='https://otus.ru/journal/wp-content/themes/contentberg/css/fontawesome/css/font-awesome.min.css?ver=1.8.3' type='text/css' media='all' />
<script type="text/javascript" id="breeze-prefetch-js-extra">
/* <![CDATA[ */
var breeze_prefetch = {"local_url":"https:\/\/otus.ru\/journal","ignore_remote_prefetch":"1","ignore_list":["\/wp-admin\/"]};
/* ]]> */
</script>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/plugins/breeze/assets/js/js-front-end/breeze-prefetch-links.min.js" id="breeze-prefetch-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-includes/js/jquery/jquery.min.js" id="jquery-core-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-includes/js/jquery/jquery-migrate.min.js" id="jquery-migrate-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/themes/contentberg/js/lazysizes.js" id="lazysizes-js"></script>
<link rel="https://api.w.org/" href="https://otus.ru/journal/wp-json/" /><link rel="alternate" type="application/json" href="https://otus.ru/journal/wp-json/wp/v2/posts/6601" /><link rel='shortlink' href='https://otus.ru/journal/?p=6601' />
<link rel="alternate" type="application/json+oembed" href="https://otus.ru/journal/wp-json/oembed/1.0/embed?url=https%3A%2F%2Fotus.ru%2Fjournal%2Ftraceback-v-pitone%2F" />
<link rel="alternate" type="text/xml+oembed" href="https://otus.ru/journal/wp-json/oembed/1.0/embed?url=https%3A%2F%2Fotus.ru%2Fjournal%2Ftraceback-v-pitone%2F&format=xml" />
<script>var Sphere_Plugin = {"ajaxurl":"https:\/\/otus.ru\/journal\/wp-admin\/admin-ajax.php"};</script><link rel="icon" href="https://otus.ru/journal/wp-content/uploads/2020/11/cropped-OTUS_logo_OTUS-COMP-LOGO-WHITE-1-32x32.png" sizes="32x32" />
<link rel="icon" href="https://otus.ru/journal/wp-content/uploads/2020/11/cropped-OTUS_logo_OTUS-COMP-LOGO-WHITE-1-192x192.png" sizes="192x192" />
<link rel="apple-touch-icon" href="https://otus.ru/journal/wp-content/uploads/2020/11/cropped-OTUS_logo_OTUS-COMP-LOGO-WHITE-1-180x180.png" />
<meta name="msapplication-TileImage" content="https://otus.ru/journal/wp-content/uploads/2020/11/cropped-OTUS_logo_OTUS-COMP-LOGO-WHITE-1-270x270.png" />
<style type="text/css" id="wp-custom-css">
#menu-item-10406 .wpel-icon {
display: none;
}
#menu-item-10407 .wpel-icon {
display: none;
}
.otus-login-site a .wpel-icon {
display: none;
}
.menu-menju-navykov-container a .wpel-icon {
display: none;
}
.otus-login-site a
{
background: #ffd709;
border-radius: 12px;
color: #0f0f10;
font-size: 14px;
font-weight: 700;
line-height: 20px;
display: block;
text-align: center;
padding: 8px 25px;
}
.main-footer.dark {
background: linear-gradient(90deg, #a64fc5, #4f54e6);
border-color: transparent;
}
.main-footer.bold .copyright {
color: #fff;
}
.main-footer.bold .to-top i {
color: #fff;
}
.main-footer.bold .back-to-top {
color: #fff;
}
.nav__scroll {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
.scrollable-menu .menu {
display: flex;
}
.nav__scroll
{
background: linear-gradient(90deg, #a64fc5, #4f54e6);
}
.scrollable-menu .menu .menu-item {
flex: 0 0 auto;
padding: 15px 15px;
}
.scrollable-menu .menu .menu-item a {
color: #fff;
}
.nav__scroll::-webkit-scrollbar{background-color:#fff;height:5px;}
.nav__scroll::-webkit-scrollbar-thumb{background-color:#dcdcdc;}
.nav__scroll::-webkit-scrollbar-track{-webkit-border-radius:0;border-radius:0;background-color:#fff;}/
body {
min-width: 320px;
}
.banner-click img {
margin: 0 auto;
display: block;
}
.banner-click {
cursor: pointer;
}
.banner-footer-area {
margin-bottom: 20px;
}
.banner-left-area {
margin-top: 40px;
} </style>
<!--Start VDZ Yandex Metrika Plugin-->
<!-- Yandex.Metrika counter --><script type="text/javascript" >(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");ym(34531570, "init", {clickmap:true, trackLinks:true, accurateTrackBounce:true, webvisor:true, trackHash:true, ecommerce:"dataLayer"});</script>
<noscript><div><img src="https://mc.yandex.ru/watch/34531570" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
<!-- /Yandex.Metrika counter --><!--START ADD EVENTS FROM CF7--><script type='text/javascript'>document.addEventListener( 'wpcf7submit', function( event ) {
//event.detail.contactFormId;
if(ym){
//console.log(event.detail);
ym(34531570, 'reachGoal', 'VDZ_SEND_CONTACT_FORM_7');
ym(34531570, 'params', {
page_url: window.location.href,
status: event.detail.status,
locale: event.detail.contactFormLocale,
form_id: event.detail.contactFormId,
});
}
}, false );
</script><!--END ADD EVENTS FROM CF7-->
<!--End VDZ Yandex Metrika Plugin-->
</head>
<body class="post-template-default single single-post postid-6601 single-format-standard right-sidebar lazy-normal has-lb">
<div class="main-wrap">
<header id="main-head" class="main-head head-nav-below has-search-modal simple simple-boxed">
<div class="inner inner-head" data-sticky-bar="0">
<div class="wrap cf wrap-head">
<div class="left-contain">
<span class="mobile-nav"><i class="fa fa-bars"></i></span>
<div class="title">
<a href="https://otus.ru/journal/" title="OTUS JOURNAL" rel="home" data-wpel-link="internal">
<span class="text-logo"><img src="/journal/wp-content/themes/contentberg/img/logo_site.svg" alt="OTUS JOURNAL"></span>
</a>
</div>
</div>
<div class="navigation-wrap inline">
<nav class="navigation inline simple light" data-sticky-bar="0">
<div class="menu-rubriki-container"><ul id="menu-rubriki" class="menu"><li id="menu-item-109" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-cat-1 menu-item-109"><a href="https://otus.ru/journal/category/pro-it/" data-wpel-link="internal"><span>Про IT</span></a></li>
<li id="menu-item-113" class="menu-item menu-item-type-taxonomy menu-item-object-category current-post-ancestor current-menu-parent current-post-parent menu-cat-4 menu-item-113"><a href="https://otus.ru/journal/category/polza/" data-wpel-link="internal"><span>Полезное</span></a></li>
<li id="menu-item-114" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-cat-3 menu-item-114"><a href="https://otus.ru/journal/category/lifestyle/" data-wpel-link="internal"><span>Лайфстайл</span></a></li>
<li id="menu-item-10406" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10406"><a href="https://otus.ru/catalog/courses" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right"><span>Обучение</span><span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li id="menu-item-10407" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10407"><a href="https://otus.ru/about" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right"><span>Информация</span><span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
</ul></div> </nav>
</div>
<div class="actions">
<div class="otus-login-site">
<a href="https://otus.ru/login/" target="_blank" data-wpel-link="external" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Войти<span class="wpel-icon wpel-image wpel-icon-6"></span></a>
</div>
<a href="#" title="Search" class="search-link"><i class="fa fa-search"></i></a>
</div>
</div>
</div>
</header> <!-- .main-head -->
<div class="nav nav_disable nav_colored nav_transparent course-categories__nav nav__scroll ">
<div class="container wrap">
<div class="links inline simple light scrollable-menu">
<div class="menu-menju-navykov-container"><ul id="menu-menju-navykov" class="menu"><li id="menu-item-10413" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10413"><a href="https://otus.ru/categories/programming/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Программирование<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li id="menu-item-10414" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10414"><a href="https://otus.ru/categories/architecture/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Архитектура<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li id="menu-item-10415" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10415"><a href="https://otus.ru/categories/operations/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Инфраструктура<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li id="menu-item-10416" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10416"><a href="https://otus.ru/categories/information-security-courses/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Безопасность<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li id="menu-item-10417" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10417"><a href="https://otus.ru/categories/data-science/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Data Science<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li id="menu-item-10418" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10418"><a href="https://otus.ru/categories/gamedev/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">GameDev<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li id="menu-item-10419" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10419"><a href="https://otus.ru/categories/marketing-business/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Управление<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li id="menu-item-10420" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10420"><a href="https://otus.ru/categories/analytics/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Аналитика и анализ<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li id="menu-item-10421" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10421"><a href="https://otus.ru/categories/testing/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Тестирование<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
</ul></div> </div>
</div>
</div>
<div class="main wrap">
<div class="ts-row cf">
<div class="col-8 main-content cf">
<article id="post-6601" class="the-post post-6601 post type-post status-publish format-standard has-post-thumbnail category-polza tag-python">
<header class="post-header the-post-header cf">
<div class="post-meta the-post-meta">
<span class="post-cat">
<a href="https://otus.ru/journal/category/polza/" class="category" data-wpel-link="internal">Полезное</a>
</span>
<h1 class="post-title">
Traceback в Питоне
</h1>
<a href="https://otus.ru/journal/traceback-v-pitone/" class="date-link" data-wpel-link="internal"><time class="post-date">6 июня, 2023</time></a>
</div>
<div class="featured">
<a href="https://otus.ru/journal/wp-content/uploads/2023/06/oj-1080x72057-1.jpg" class="image-link" data-wpel-link="internal"><img width="770" height="515" src="data:image/svg+xml,%3Csvg%20viewBox%3D%270%200%20770%20515%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%3C%2Fsvg%3E" class="attachment-contentberg-main size-contentberg-main lazyload wp-post-image" alt="Traceback в Питоне" title="Traceback в Питоне" decoding="async" fetchpriority="high" data-srcset="https://otus.ru/journal/wp-content/uploads/2023/06/oj-1080x72057-1-770x515.jpg 770w, https://otus.ru/journal/wp-content/uploads/2023/06/oj-1080x72057-1-270x180.jpg 270w" data-src="https://otus.ru/journal/wp-content/uploads/2023/06/oj-1080x72057-1-770x515.jpg" data-sizes="(max-width: 770px) 100vw, 770px" /> </a>
</div>
</header><!-- .post-header -->
<div class="post-content description cf entry-content content-normal">
<div id="ez-toc-container" class="ez-toc-v2_0_61 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction">
<div class="ez-toc-title-container">
<p class="ez-toc-title " >Содержание</p>
<span class="ez-toc-title-toggle"><a href="#" class="ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle" aria-label="Toggle Table of Content"><span class="ez-toc-js-icon-con"><span class=""><span class="eztoc-hide" style="display:none;">Toggle</span><span class="ez-toc-icon-toggle-span"><svg style="fill: #999;color:#999" xmlns="http://www.w3.org/2000/svg" class="list-377408" width="20px" height="20px" viewBox="0 0 24 24" fill="none"><path d="M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z" fill="currentColor"></path></svg><svg style="fill: #999;color:#999" class="arrow-unsorted-368013" xmlns="http://www.w3.org/2000/svg" width="10px" height="10px" viewBox="0 0 24 24" version="1.2" baseProfile="tiny"><path d="M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z"/></svg></span></span></span></a></span></div>
<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class="ez-toc-link ez-toc-heading-1" href="#%D0%9E%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5" title="Определение">Определение</a></li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class="ez-toc-link ez-toc-heading-2" href="#%D0%9F%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D0%B0_%D1%87%D1%82%D0%B5%D0%BD%D0%B8%D1%8F_traceback" title="Правила чтения traceback">Правила чтения traceback</a></li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class="ez-toc-link ez-toc-heading-3" href="#%D0%9D%D0%B0%D0%B3%D0%BB%D1%8F%D0%B4%D0%BD%D1%8B%D0%B5_%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D1%8B_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2" title="Наглядные примеры кодов">Наглядные примеры кодов</a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class="ez-toc-link ez-toc-heading-4" href="#%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80_2" title="Пример 2">Пример 2</a></li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class="ez-toc-link ez-toc-heading-5" href="#%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80_3_%E2%80%93_%D0%BA%D0%B0%D0%BA_%D0%BD%D0%B5_%D0%B7%D0%B0%D0%BF%D1%83%D1%82%D0%B0%D1%82%D1%8C%D1%81%D1%8F_%D0%B2_%D0%BE%D1%82%D1%87%D0%B5%D1%82%D0%B0%D1%85" title="Пример 3 – как не запутаться в отчетах">Пример 3 – как не запутаться в отчетах</a></li></ul></li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class="ez-toc-link ez-toc-heading-6" href="#%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D1%8B%D0%B5_traceback_%D0%B8%D1%81%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D1%8F" title="Основные traceback исключения">Основные traceback исключения</a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class="ez-toc-link ez-toc-heading-7" href="#AttributeError" title="AttributeError">AttributeError</a></li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class="ez-toc-link ez-toc-heading-8" href="#ImportError" title="ImportError">ImportError</a></li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class="ez-toc-link ez-toc-heading-9" href="#IndexError" title="IndexError">IndexError</a></li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class="ez-toc-link ez-toc-heading-10" href="#KeyError" title="KeyError">KeyError</a></li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class="ez-toc-link ez-toc-heading-11" href="#NameError" title="NameError">NameError</a></li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class="ez-toc-link ez-toc-heading-12" href="#SyntaxError" title="SyntaxError">SyntaxError</a></li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class="ez-toc-link ez-toc-heading-13" href="#TypeError" title="TypeError">TypeError</a></li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class="ez-toc-link ez-toc-heading-14" href="#ValueError" title="ValueError">ValueError</a></li></ul></li></ul></nav></div>
<p>Traceback в Python – процесс, с которым может рано или поздно столкнуться любой разработчик. Соответствующий компонент необходимо грамотно считывать и обрабатывать. В противном случае от него не будет никакого толку, а исправить ситуацию станет практически невозможно. Связано это с тем, что traceback exception тесно связан с ошибками, возникающими при компиляции кода.</p>
<p>Несмотря на то, что изначально соответствующий элемент выглядит устрашающе (особенно для новичков), информация в нем будет крайне полезной при отладке программного обеспечения. Далее предстоит получше изучить упомянутый компонент, а также познакомиться с его исключениями. Предложенная информация будет полезна как новичкам, так и более опытным разработчика. Она больше ориентирована на тех, кто уже имеет хоть какой-то опыт в разработке на the Python 3.</p>
<h2 class="wp-block-heading"><span class="ez-toc-section" id="%D0%9E%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5"></span>Определение<span class="ez-toc-section-end"></span></h2>
<p>The traceback exception – это трассировка. Она представляет собой отчет, который включает в себя информацию о вызовах выполненных функций программного кода в тот или иной момент. Появляется рассматриваемый элемент во время обнаружения ошибок реализации (компиляции) программы.</p>
<p>Трассировка описывается различными терминами. Примеры – трассировка стека или обратная трассировка. Далее будет использоваться понятие the traceback или просто «трассировка».</p>
<p>Каждый раз, когда Python выдает исключение или error, система выводит на экран специальное сообщение. Оно и будет является трассировкой. Данный отчет помогает понять, что пошло не так. Ниже можно увидеть наглядный пример рассматриваемого элемента.</p>
<figure class="wp-block-image size-full"><img decoding="async" width="261" height="82" src="https://otus.ru/journal/wp-content/uploads/2023/06/image-83.png" alt="Traceback в Питоне" class="wp-image-6602" srcset="https://otus.ru/journal/wp-content/uploads/2023/06/image-83.png 261w, https://otus.ru/journal/wp-content/uploads/2023/06/image-83-150x47.png 150w" sizes="(max-width: 261px) 100vw, 261px" /></figure>
<p>В заданном примере:</p>
<ol>
<li>Происходит вызов функции greet. У нее есть параметр – someone.</li>
<li>В greet это имя переменной не используется.</li>
<li>Вместо соответствующего действия переменная someone указана при вызове функции на печать в print.</li>
</ol>
<p>Описанная ситуация приведет к появлению ошибки. После обработки представленного фрагмента исходного кода на дисплее появится такой отчет:</p>
<figure class="wp-block-image size-full"><img decoding="async" width="428" height="110" src="https://otus.ru/journal/wp-content/uploads/2023/06/image-84.png" alt="Traceback в Питоне" class="wp-image-6603" srcset="https://otus.ru/journal/wp-content/uploads/2023/06/image-84.png 428w, https://otus.ru/journal/wp-content/uploads/2023/06/image-84-300x77.png 300w, https://otus.ru/journal/wp-content/uploads/2023/06/image-84-150x39.png 150w" sizes="(max-width: 428px) 100vw, 428px" /></figure>
<p>Здесь содержится вся информация, которая поможет при диагностике error. Последняя строка вывода указывает на то, какой тип исключения генерировался вместе с некоторыми данными об исключении. Предыдущие строчки описывают причину генерации exception.</p>
<p>В предложенном the stacktrace в виде исключения выступает NameError. Это значит, что есть ссылка на какое-то имя (переменная, класс или функциям), которое не удалось определить. Здесь это – someone.</p>
<p>Последняя строчка в сложившейся ситуации располагает достаточной информацией о том, чтобы помочь разработчику исправить ситуацию. Поиск кода через имя someone, который выступает орфографической ошибкой, укажет на правильное дальнейшее «движение». Это элементарный случай, но на практике обычно code сложнее. И трассировку приходится грамотно считывать.</p>
<h2 class="wp-block-heading"><span class="ez-toc-section" id="%D0%9F%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D0%B0_%D1%87%D1%82%D0%B5%D0%BD%D0%B8%D1%8F_traceback"></span>Правила чтения traceback<span class="ez-toc-section-end"></span></h2>
<p>Traceback – это отчет, который необходимо грамотно считывать, чтобы понять причину ошибки, которая возникла in the code. Далее предстоит более детально изучить разнообразие виды the stacktrace, которые помогут лучше осознать разницу между имеющейся в «документации» информации.</p>
<p>Существуют различные секции для каждой трассировки. Такое разделение является крайне важным моментом. Вот диаграмма the stack trace, которая описывает несколько областей отчета:</p>
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="578" height="258" src="https://otus.ru/journal/wp-content/uploads/2023/06/image-85.png" alt="Traceback в Питоне" class="wp-image-6604" srcset="https://otus.ru/journal/wp-content/uploads/2023/06/image-85.png 578w, https://otus.ru/journal/wp-content/uploads/2023/06/image-85-300x134.png 300w, https://otus.ru/journal/wp-content/uploads/2023/06/image-85-150x67.png 150w" sizes="(max-width: 578px) 100vw, 578px" /></figure>
<p>Отличительной чертой traceback в Питоне является порядок чтения. Чтобы лучше и быстрее разобраться с предложенными данными, «документация» должна считываться в направлении «снизу–вверх».</p>
<p>Здесь:</p>
<ol>
<li>Синяя область – это последняя строка из the traceback. Она указывает на уведомление об ошибке (error). Синий фрагмент – это непосредственное названия возникшего в процессе обработки code сбоя.</li>
<li>Зеленая область, которая указана после ошибки в the traceback exception – непосредственное описание. В соответствующем блоке прописываются сведения, которые помогают разобраться в истинных причинах возникновения сбоя.</li>
<li>Желтая область – блок, в котором описаны разнообразные вызовы функций. Записи ведутся в направлении «снизу–вверх» от самых последних до самых первых. Эти вызовы представляются двухстрочными вводами для каждой записи. Первая строчка в очередном вызове включает в себя данные в виде: названия файла, номер строки и название модуля (in module). Все это помогает выяснить, где может быть обнаружен код.</li>
<li>Красное подчеркивание. Это – вторая строка соответствующих вызовов в Python traceback. Она включает в себя непосредственный код, в котором был обнаружен сбой.</li>
</ol>
<p>Существует разница между выдачей трассировок, когда разработчик запускает код в командной строке, а также между import traceback в REPL. Ниже – наглядный пример уже рассмотренного раздела. Он активирован через REPL. Трассировка в этом случае будет выглядеть иначе:</p>
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="597" height="281" src="https://otus.ru/journal/wp-content/uploads/2023/06/image-86.png" alt="Traceback в Питоне" class="wp-image-6605" srcset="https://otus.ru/journal/wp-content/uploads/2023/06/image-86.png 597w, https://otus.ru/journal/wp-content/uploads/2023/06/image-86-300x141.png 300w, https://otus.ru/journal/wp-content/uploads/2023/06/image-86-150x71.png 150w" sizes="(max-width: 597px) 100vw, 597px" /></figure>
<p>В месте названия файла тут написано stdin. Выполненные строки в таком отчете не будут отображаться.</p>
<p>Стоит обратить внимание на то, что the stack trace в Питоне отличается от отчетов в других языках разработки. Ключевая разница заключается в том, что большинство ЯП предлагают вывод ошибки (the error) в самом начале. Далее в направлении «сверху–вниз» записывается необходимая информация от недавних до последних реализованных.</p>
<h2 class="wp-block-heading"><span class="ez-toc-section" id="%D0%9D%D0%B0%D0%B3%D0%BB%D1%8F%D0%B4%D0%BD%D1%8B%D0%B5_%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D1%8B_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2"></span>Наглядные примеры кодов<span class="ez-toc-section-end"></span></h2>
<p>Чтобы лучше понимать import traceback, а также научиться считывать трассировку в том или ином случае, рекомендуется рассматривать отчеты на наглядных примерах. Только после этого предстоит познакомиться поближе с возможными исключениями.</p>
<p>Вот – код, который записан в файле greetings.py. Он будет использоваться для наглядного примера и подробного разбора появившейся отчетности:</p>
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="576" height="224" src="https://otus.ru/journal/wp-content/uploads/2023/06/image-88.png" alt="Traceback в Питоне" class="wp-image-6607" srcset="https://otus.ru/journal/wp-content/uploads/2023/06/image-88.png 576w, https://otus.ru/journal/wp-content/uploads/2023/06/image-88-300x117.png 300w, https://otus.ru/journal/wp-content/uploads/2023/06/image-88-150x58.png 150w" sizes="(max-width: 576px) 100vw, 576px" /></figure>
<p>Соответствующий фрагмент работает так:</p>
<ol>
<li>Функция who_to_greet будет принимать значение person. Она вернет или соответствующее значение (если оно не является пустым), или запросит информацию от пользовательского ввода.</li>
<li>Для того, чтобы клиент мог вводить сведения в приложение, используется input.</li>
<li>После этого greet будет брать имя для приветствия из someone, необязательный параметр из greeting.</li>
<li>После этого система потребует сведения на вывод. Операция осуществляется посредством print.</li>
<li>Вместе с переданным значением из someone будет вызвана функция who_to_greet.</li>
<li>Теперь greet_many будет выполнять итерации по списку людей. Это приведет к вызову greet.</li>
<li>Если при работе с greet возникает сбой (ошибка), выводится резервное приветствие. Оно выражается записью print («hi» + person).</li>
</ol>
<p>Предложенный выше фрагмент кода является правильным. Ошибок он вызывать не должен. Если добавить вызов функции greet в конце исходного документа, а также передать аргумент, который является для системы неожиданным (пример – greet (“Chad”, greeting = “Хай”)), система выдаст ошибку. На экране появится the stack trace:</p>
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="539" height="119" src="https://otus.ru/journal/wp-content/uploads/2023/06/image-91.png" alt="Traceback в Питоне" class="wp-image-6610" srcset="https://otus.ru/journal/wp-content/uploads/2023/06/image-91.png 539w, https://otus.ru/journal/wp-content/uploads/2023/06/image-91-300x66.png 300w, https://otus.ru/journal/wp-content/uploads/2023/06/image-91-150x33.png 150w" sizes="(max-width: 539px) 100vw, 539px" /></figure>
<p>Предложенный отчет рекомендуется считывать снизу–вверх. В последней строчке the traces появляется ошибка Type Error. Все сообщения, идущие после типа сбоя, отображают важные для обработки сбоя сведения. Отчет указывает на то, что greet вызывался с аргументом, который не поддерживается (не ожидается) системой. Неизвестный параметр тоже отображается. В заданном примере – это greeting.</p>
<p>Если подняться по «коду» чуть выше, можно увидеть строчку, в котором появилось исключение. Ей выступает greet, которая была добавлена в самом конце greetings.py.</p>
<p>Далее отображается строка, указывающая на путь к файлу, в котором находится код, номер строки соответствующего файла, где именно расположен код, а также информацию о его модуле. В предложенном фрагменте никаких модулей нет, поэтому в необходимых строчках будет отображена информация о том, что файл является исполняемым.</p>
<h3 class="wp-block-heading"><span class="ez-toc-section" id="%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80_2"></span>Пример 2<span class="ez-toc-section-end"></span></h3>
<p>А вот еще один вариант работы с traceback. В нем в качестве «основы» будет использоваться ранее рассмотренный фрагмент. В нем удаляется greet в самом конце. Вместе этого необходимо добавить файл под названием example.py в папку:</p>
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="271" height="60" src="https://otus.ru/journal/wp-content/uploads/2023/06/image-90.png" alt="Traceback в Питоне" class="wp-image-6609" srcset="https://otus.ru/journal/wp-content/uploads/2023/06/image-90.png 271w, https://otus.ru/journal/wp-content/uploads/2023/06/image-90-150x33.png 150w" sizes="(max-width: 271px) 100vw, 271px" /></figure>
<p>Тут происходит настройка еще одного Python-файла. Он требуется для импорта предыдущего модуля greetings.py. Далее разработчик будет использовать соответствующий «новый» документ в функции greet. Если запустить example.py, произойдет следующее:</p>
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="450" height="156" src="https://otus.ru/journal/wp-content/uploads/2023/06/image-92.png" alt="Traceback в Питоне" class="wp-image-6611" srcset="https://otus.ru/journal/wp-content/uploads/2023/06/image-92.png 450w, https://otus.ru/journal/wp-content/uploads/2023/06/image-92-300x104.png 300w, https://otus.ru/journal/wp-content/uploads/2023/06/image-92-150x52.png 150w" sizes="(max-width: 450px) 100vw, 450px" /></figure>
<p>В этом Python traceback:</p>
<ol>
<li>Снова возникает ошибка TypeError.</li>
<li>На этот раз в отчетности можно увидеть сообщение, которое будет не слишком полезно разработчику. Это значит, что где-то в программном коде ожидается работа со строкой, но было передано целое число.</li>
<li>Если подняться чуть выше, программист увидит фрагмент, который будет обработан системой. Далее указывается файл и номер кодовой строчки.</li>
<li>Здесь разработчик получил имя функции greet. Она была успешно выполнена в процессе очередной итерации.</li>
<li>Еще выше в the traceback можно увидеть «проблемный» вызов greet. Он передает целочисленное значение, что впоследствии приводит к сбою.</li>
</ol>
<p>Python exception-traceback после появления ошибки может взять другой блок кода и вывести его в отчетности. При подобных обстоятельствах Питон выведет все трассировки ошибки в том порядке, в котором они были получены. За счет подобной особенности разработчики сумеют отследить, где именно начался сбой. В traceback заканчиваться документация будет самой последней трассировкой.</p>
<h3 class="wp-block-heading"><span class="ez-toc-section" id="%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80_3_%E2%80%93_%D0%BA%D0%B0%D0%BA_%D0%BD%D0%B5_%D0%B7%D0%B0%D0%BF%D1%83%D1%82%D0%B0%D1%82%D1%8C%D1%81%D1%8F_%D0%B2_%D0%BE%D1%82%D1%87%D0%B5%D1%82%D0%B0%D1%85"></span>Пример 3 – как не запутаться в отчетах<span class="ez-toc-section-end"></span></h3>
<p>Чтобы лучше разобраться в последней описанной ситуации, разработчикам рекомендуется изучить наглядный пример. В качестве базового кода будет использоваться уже известный по предыдущим кодам и отчетностям. В самом конце greetings.py рекомендуется добавить вызов greet_many:</p>
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="296" height="62" src="https://otus.ru/journal/wp-content/uploads/2023/06/image-89.png" alt="Traceback в Питоне" class="wp-image-6608" srcset="https://otus.ru/journal/wp-content/uploads/2023/06/image-89.png 296w, https://otus.ru/journal/wp-content/uploads/2023/06/image-89-150x31.png 150w" sizes="(max-width: 296px) 100vw, 296px" /></figure>
<p>Соответствующая ситуация приводит к выводу приветствия для трех человек. Если запустить получившийся в конечном итоге, на выходе получатся сразу несколько трассировок (python print traceback):</p>
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="575" height="334" src="https://otus.ru/journal/wp-content/uploads/2023/06/image-95.png" alt="Traceback в Питоне" class="wp-image-6614" srcset="https://otus.ru/journal/wp-content/uploads/2023/06/image-95.png 575w, https://otus.ru/journal/wp-content/uploads/2023/06/image-95-300x174.png 300w, https://otus.ru/journal/wp-content/uploads/2023/06/image-95-150x87.png 150w" sizes="(max-width: 575px) 100vw, 575px" /></figure>
<p>Стоит обратить внимание на выделенную строку, которая начинается с «During handling…». Она используется для того, чтобы разделять the stacktraces. Подобная запись сигнализирует о том, что при попытке обработать предыдущий сбой, появилась новая ошибка.</p>
<p>Еще один момент – это возможность отображения предыдущих трассировок. Подобная функциональность появилась не сразу. Ее разработчики Python добавили в 3 версии. В более ранних сборках языка на экране будет выводиться только последняя ошибка.</p>
<p>Предыдущая ошибка могла быть замечена разработчиком при вызове greet() с целочисленным параметром. При добавлении 1 в список людей для приветствия, ожидается точно такой же результат. Только функция greet_many оборачивает вызов greet. После этого она пытается работать в блоках try и an except. Если greet приведет в ошибке, greet_many выведет приветствие по умолчанию.</p>
<p>Тут повторяется соответствующая часть greetings.py:</p>
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="360" height="116" src="https://otus.ru/journal/wp-content/uploads/2023/06/image-94.png" alt="Traceback в Питоне" class="wp-image-6613" srcset="https://otus.ru/journal/wp-content/uploads/2023/06/image-94.png 360w, https://otus.ru/journal/wp-content/uploads/2023/06/image-94-300x97.png 300w, https://otus.ru/journal/wp-content/uploads/2023/06/image-94-150x48.png 150w" sizes="(max-width: 360px) 100vw, 360px" /></figure>
<p>Здесь:</p>
<ol>
<li>Когда greet приведет к TypeError traceback из-за неправильного ввода числа, greet_many обработает возникший сбой.</li>
<li>Результатом выполненных операций станет попытка вывода простого приветствия.</li>
<li>Это повлечет за собой новый сбой. Система все еще пытается добавить строчку и целое число.</li>
</ol>
<p>Если внимательно просмотреть весь traceback, можно заметить, что именно послужило причиной ошибок. Бывают ситуации, при которых программист получает только последний сбой с последующей traceback. В этом случае проблематично отследить, где и что пошло не по плану. Исправить положение удастся за счет рассмотрения предыдущих ошибок и сбоев.</p>
<h2 class="wp-block-heading"><span class="ez-toc-section" id="%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D1%8B%D0%B5_traceback_%D0%B8%D1%81%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D1%8F"></span>Основные traceback исключения<span class="ez-toc-section-end"></span></h2>
<p>Ускорить процесс понимания the traceback поможет более детальное изучение исключений. Навыки различать разнообразные трассировки значительно упрощают процедуру отладки программного обеспечения. Далее представлены the exception traceback, которые встречаются в разработке чаще всего.</p>
<h3 class="wp-block-heading"><span class="ez-toc-section" id="AttributeError"></span>AttributeError<span class="ez-toc-section-end"></span></h3>
<p>The AttributeError появляется тогда, когда программист пытается получить доступ к атрибуту объекта (object), который не имеет конкретного атрибута. В официальной документации языка говорится о том, что она возникает при вызове несуществующего атрибута или при присвоении значения несуществующему атрибуту.</p>
<p>Вот – наглядный пример такой ошибки:</p>
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="516" height="112" src="https://otus.ru/journal/wp-content/uploads/2023/06/image-87.png" alt="Traceback в Питоне" class="wp-image-6606" srcset="https://otus.ru/journal/wp-content/uploads/2023/06/image-87.png 516w, https://otus.ru/journal/wp-content/uploads/2023/06/image-87-300x65.png 300w, https://otus.ru/journal/wp-content/uploads/2023/06/image-87-150x33.png 150w" sizes="(max-width: 516px) 100vw, 516px" /></figure>
<p>В строке уведомления о произошедшем AttributeError указано о том, что определенных тип объекта (int) не имеет доступа к атрибуту (an_attribute). За счет более детального изучения отчетности разработчик сможет быстро понять, куда пыталась перейти система, а также дальнейший алгоритм действия для устранения неполадок.</p>
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="502" height="115" src="https://otus.ru/journal/wp-content/uploads/2023/06/image-98.png" alt="Traceback в Питоне" class="wp-image-6617" srcset="https://otus.ru/journal/wp-content/uploads/2023/06/image-98.png 502w, https://otus.ru/journal/wp-content/uploads/2023/06/image-98-300x69.png 300w, https://otus.ru/journal/wp-content/uploads/2023/06/image-98-150x34.png 150w" sizes="(max-width: 502px) 100vw, 502px" /></figure>
<p>Рассматриваемый the exception traceback в основном указывает на то, что программист работает с объектом, тип которого не является ожидаемым. Эта ситуация наглядно продемонстрирована выше. Тут:</p>
<ol>
<li>Можно ожидать, что a_list будет являться типом списка, который включает в себя метод .append.</li>
<li>При получении the AttributeError указывается, что сбой произошел в упомянутом ранее методе.</li>
<li>Соответствующая ситуация указывает на то, что программист может иметь дело с типом объекта, который не ожидается системой.</li>
</ol>
<p>Подобная ситуация возможно тогда, когда разработчик ожидает, что объект вернется из вызова функции или метода, а также будет относиться к определенному типу, но «на выходе» получается тип объекта None. В соответствующем случае the traceback будет выглядеть так:</p>
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="452" height="49" src="https://otus.ru/journal/wp-content/uploads/2023/06/image-101.png" alt="Traceback в Питоне" class="wp-image-6620" srcset="https://otus.ru/journal/wp-content/uploads/2023/06/image-101.png 452w, https://otus.ru/journal/wp-content/uploads/2023/06/image-101-300x33.png 300w, https://otus.ru/journal/wp-content/uploads/2023/06/image-101-150x16.png 150w" sizes="(max-width: 452px) 100vw, 452px" /></figure>
<p>Это – не единственное исключение, которое может быть вызвано системой. Разработчики могут сталкиваться и с другими сбоями.</p>
<h3 class="wp-block-heading"><span class="ez-toc-section" id="ImportError"></span>ImportError<span class="ez-toc-section-end"></span></h3>
<p>The ImportError – это сигнализация о том, что что-то не так с оператором import. Traceback exception или ее подкласс, который называется ModuleNotFoundError возникает тогда, когда модуль, который импортируется, не может быть обнаружен. Аналогично ситуация обстоит с импортом того, что не существует в системе. В документации указано следующее:</p>
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="566" height="82" src="https://otus.ru/journal/wp-content/uploads/2023/06/image-103.png" alt="Traceback в Питоне" class="wp-image-6622" srcset="https://otus.ru/journal/wp-content/uploads/2023/06/image-103.png 566w, https://otus.ru/journal/wp-content/uploads/2023/06/image-103-300x43.png 300w, https://otus.ru/journal/wp-content/uploads/2023/06/image-103-150x22.png 150w" sizes="(max-width: 566px) 100vw, 566px" /></figure>
<p>Выглядят The ImportError и ModuleNotFountError так:</p>
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="381" height="168" src="https://otus.ru/journal/wp-content/uploads/2023/06/image-104.png" alt="Traceback в Питоне" class="wp-image-6623" srcset="https://otus.ru/journal/wp-content/uploads/2023/06/image-104.png 381w, https://otus.ru/journal/wp-content/uploads/2023/06/image-104-300x132.png 300w, https://otus.ru/journal/wp-content/uploads/2023/06/image-104-150x66.png 150w" sizes="(max-width: 381px) 100vw, 381px" /></figure>
<p>Заданный пример показывает, что попытка импорта модуля asdf, которого не существует, приводит к образованию the ModuleNotFound. Если же попытаться импортировать то, что не существует (в соответствующем случае – asdf) из модуля, которого нет (collections), произойдет сбой типа ImportError. Строки сообщения о the traceback error in Python указывают на то, что именно не может быть импортировано. В приведенной ситуации в обоих случаях это asdf.</p>
<h3 class="wp-block-heading"><span class="ez-toc-section" id="IndexError"></span>IndexError<span class="ez-toc-section-end"></span></h3>
<p>The IndexError Traceback выводится тогда, когда разработчик пытается вернуть индекс из имеющейся последовательности (списка, кортежа), но соответствующий компонент не может быть обнаружен. В документации указывается следующее:</p>
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="528" height="49" src="https://otus.ru/journal/wp-content/uploads/2023/06/image-109.png" alt="Traceback в Питоне" class="wp-image-6628" srcset="https://otus.ru/journal/wp-content/uploads/2023/06/image-109.png 528w, https://otus.ru/journal/wp-content/uploads/2023/06/image-109-300x28.png 300w, https://otus.ru/journal/wp-content/uploads/2023/06/image-109-150x14.png 150w" sizes="(max-width: 528px) 100vw, 528px" /></figure>
<p>А вот пример, обработка которого приведет к IndexError:</p>
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="328" height="120" src="https://otus.ru/journal/wp-content/uploads/2023/06/image-110.png" alt="Traceback в Питоне" class="wp-image-6629" srcset="https://otus.ru/journal/wp-content/uploads/2023/06/image-110.png 328w, https://otus.ru/journal/wp-content/uploads/2023/06/image-110-300x110.png 300w, https://otus.ru/journal/wp-content/uploads/2023/06/image-110-150x55.png 150w" sizes="(max-width: 328px) 100vw, 328px" /></figure>
<p>Здесь:</p>
<ol>
<li>Строка сообщения об ошибке IndexError не дает полноценную информацию.</li>
<li>Разработчик может увидеть, что имеется отсылка к последовательности, которая не доступна.</li>
<li>Дополнительно отображаются сведения о том, какой тип последовательностей используется в приложении. В рассматриваемом примере им является список.</li>
</ol>
<p>Простыми словами: в списке a_list нет значения с ключом 3. Поддерживаются только параметры с ключами 0 и 1, что значит a и b соответственно.</p>
<p>Рассматривать IndexError рекомендуется вместе с остальными трассировками. Лишь в этом случае удается полноценно отследить источник проблемы и оперативно устранить его.</p>
<h3 class="wp-block-heading"><span class="ez-toc-section" id="KeyError"></span>KeyError<span class="ez-toc-section-end"></span></h3>
<p>Возникает KeyError в тех же ситуациях, что и в случае с the IndexError – когда разработчик пытается получить доступ к ключу, который отсутствует в отображении. Обычно это dict (словарь). KeyError может рассматриваться как IndexError для словарей в программном коде. Вот так выглядит высказывание о трассировке для словарей:</p>
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="515" height="45" src="https://otus.ru/journal/wp-content/uploads/2023/06/image-108.png" alt="Traceback в Питоне" class="wp-image-6627" srcset="https://otus.ru/journal/wp-content/uploads/2023/06/image-108.png 515w, https://otus.ru/journal/wp-content/uploads/2023/06/image-108-300x26.png 300w, https://otus.ru/journal/wp-content/uploads/2023/06/image-108-150x13.png 150w" sizes="(max-width: 515px) 100vw, 515px" /></figure>
<p>Наглядный пример the KeyError traceback:</p>
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="336" height="115" src="https://otus.ru/journal/wp-content/uploads/2023/06/image-107.png" alt="Traceback в Питоне" class="wp-image-6626" srcset="https://otus.ru/journal/wp-content/uploads/2023/06/image-107.png 336w, https://otus.ru/journal/wp-content/uploads/2023/06/image-107-300x103.png 300w, https://otus.ru/journal/wp-content/uploads/2023/06/image-107-150x51.png 150w" sizes="(max-width: 336px) 100vw, 336px" /></figure>
<p>В строке уведомления KeyError говорится о ключе, который не может быть обнаружен системой. Этого мало для исправления ситуации, поэтому предстоит изучить остальную часть трассировки для отладки программного кода.</p>
<h3 class="wp-block-heading"><span class="ez-toc-section" id="NameError"></span>NameError<span class="ez-toc-section-end"></span></h3>
<p>Сбой, который отображается, если разработчик ссылается на название модуля, переменной, функции, класса или иного компонента, имя которой не определено в коде. В официальной документации the Python указано следующее:</p>
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="507" height="45" src="https://otus.ru/journal/wp-content/uploads/2023/06/image-106.png" alt="Traceback в Питоне" class="wp-image-6625" srcset="https://otus.ru/journal/wp-content/uploads/2023/06/image-106.png 507w, https://otus.ru/journal/wp-content/uploads/2023/06/image-106-300x27.png 300w, https://otus.ru/journal/wp-content/uploads/2023/06/image-106-150x13.png 150w" sizes="(max-width: 507px) 100vw, 507px" /></figure>
<p>А вот – код, в котором greet будет брать в качестве параметра person. В задействованной функции соответствующее значение описано как person. Это ошибка, которая приведет к трассировке:</p>
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="406" height="150" src="https://otus.ru/journal/wp-content/uploads/2023/06/image-105.png" alt="Traceback в Питоне" class="wp-image-6624" srcset="https://otus.ru/journal/wp-content/uploads/2023/06/image-105.png 406w, https://otus.ru/journal/wp-content/uploads/2023/06/image-105-300x111.png 300w, https://otus.ru/journal/wp-content/uploads/2023/06/image-105-150x55.png 150w" sizes="(max-width: 406px) 100vw, 406px" /></figure>
<p>Строка уведомления об ошибке traceback NameError указывает на непосредственное название искомой функции. Приведенный пример вызывает его с ошибкой.</p>
<p>NameError также может выскакивать, если разработчик неправильно называет параметр:</p>
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="367" height="152" src="https://otus.ru/journal/wp-content/uploads/2023/06/image-102.png" alt="Traceback в Питоне" class="wp-image-6621" srcset="https://otus.ru/journal/wp-content/uploads/2023/06/image-102.png 367w, https://otus.ru/journal/wp-content/uploads/2023/06/image-102-300x124.png 300w, https://otus.ru/journal/wp-content/uploads/2023/06/image-102-150x62.png 150w" sizes="(max-width: 367px) 100vw, 367px" /></figure>
<p>В этом примере все кажется так, словно разработчик написал правильный и грамотный код. Последняя строка, которая была обработана (на нее же ссылается трассировка) выглядит хорошо.</p>
<p>В подобном случае рекомендуется внимательно изучить исходный код приложения. Необходимо найти участок, где переменная person определялась и использовалась. За счет этого получится увидеть, что название параметра введено с ошибкой.</p>
<h3 class="wp-block-heading"><span class="ez-toc-section" id="SyntaxError"></span>SyntaxError<span class="ez-toc-section-end"></span></h3>
<p>Возникает, когда синтаксический анализатор обнаруживает ошибку. Указывает на то, что разработчик неправильно написал код. Принципы, предусматриваемые синтаксисом Python, не соблюдены.</p>
<p>Вот – пример, где import traceback заключается в отсутствии двоеточия. Оно должно быть расположено в конце строки определения функции. В REPL подобная ситуация возникнет сразу после того, как программист нажмет на Enter:</p>
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="256" height="101" src="https://otus.ru/journal/wp-content/uploads/2023/06/image-100.png" alt="Traceback в Питоне" class="wp-image-6619" srcset="https://otus.ru/journal/wp-content/uploads/2023/06/image-100.png 256w, https://otus.ru/journal/wp-content/uploads/2023/06/image-100-150x59.png 150w" sizes="(max-width: 256px) 100vw, 256px" /></figure>
<p>В строке уведомления будет указано только о том, что имеется проблема синтаксического характера. Обычно информация, написанная над SyntaxError, помогает выяснить причину происходящего. Каретка ^ часто сигнализирует о «проблемной» области. В приведенном примере – это отсутствие двоеточия в операторе def заданной функции.</p>
<p>В случае с трассировками типа SyntaxError, привычная первая строка the import-traceback будет отсутствовать. Ситуация складывается из-за того, что SyntaxError возникает в момент, когда Python пытается парсить исходный код. Фактически строки выполняться не будут.</p>
<h3 class="wp-block-heading"><span class="ez-toc-section" id="TypeError"></span>TypeError<span class="ez-toc-section-end"></span></h3>
<p>The TypeError появляется тогда, когда программный код пытается выполнить действия с объектом, который не может этого сделать. Пример – попытка добавления строки в целое число или вызов len для объекта, в котором отсутствует определение длины.</p>
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="493" height="67" src="https://otus.ru/journal/wp-content/uploads/2023/06/image-99.png" alt="Traceback в Питоне" class="wp-image-6618" srcset="https://otus.ru/journal/wp-content/uploads/2023/06/image-99.png 493w, https://otus.ru/journal/wp-content/uploads/2023/06/image-99-300x41.png 300w, https://otus.ru/journal/wp-content/uploads/2023/06/image-99-150x20.png 150w" sizes="(max-width: 493px) 100vw, 493px" /></figure>
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="561" height="257" src="https://otus.ru/journal/wp-content/uploads/2023/06/image-97.png" alt="Traceback в Питоне" class="wp-image-6616" srcset="https://otus.ru/journal/wp-content/uploads/2023/06/image-97.png 561w, https://otus.ru/journal/wp-content/uploads/2023/06/image-97-300x137.png 300w, https://otus.ru/journal/wp-content/uploads/2023/06/image-97-150x69.png 150w" sizes="(max-width: 561px) 100vw, 561px" /></figure>
<p>Выше можно увидеть сразу несколько примеров TypeError. В строке уведомления будет появляться различная информация. Каждый такой компонент предоставляет достаточную информацию о том, что пошло не так.</p>
<p>Первые два примера – это ввод строк и целых чисел совместно:</p>
<ul>
<li>первый пример – попытка добавить str K int;</li>
<li>второй пример – добавление int K str.</li>
</ul>
<p>На соответствующие различия ссылаются предоставленные уведомления. В последнем примере разработчик пытается вызвать len для int. С целочисленными значениями подобная операция невозможна. Из-за этого возникает исключение TypeError.</p>
<h3 class="wp-block-heading"><span class="ez-toc-section" id="ValueError"></span>ValueError<span class="ez-toc-section-end"></span></h3>
<p>ValueError выскакивает тогда, когда значения объектов не являются корректными. Соответствующее исключение может рассматриваться в качестве IndexError, которая возникает ввиду расположения индекса вне используемого диапазона. ValueError traceback служит более обобщенным случаем.</p>
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="534" height="82" src="https://otus.ru/journal/wp-content/uploads/2023/06/image-96.png" alt="Traceback в Питоне" class="wp-image-6615" srcset="https://otus.ru/journal/wp-content/uploads/2023/06/image-96.png 534w, https://otus.ru/journal/wp-content/uploads/2023/06/image-96-300x46.png 300w, https://otus.ru/journal/wp-content/uploads/2023/06/image-96-150x23.png 150w" sizes="(max-width: 534px) 100vw, 534px" /></figure>
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="500" height="167" src="https://otus.ru/journal/wp-content/uploads/2023/06/image-93.png" alt="Traceback в Питоне" class="wp-image-6612" srcset="https://otus.ru/journal/wp-content/uploads/2023/06/image-93.png 500w, https://otus.ru/journal/wp-content/uploads/2023/06/image-93-300x100.png 300w, https://otus.ru/journal/wp-content/uploads/2023/06/image-93-150x50.png 150w" sizes="(max-width: 500px) 100vw, 500px" /></figure>
<p>В строке уведомления ValueError в приведенных выше примерах точно указано, где кроется проблема:</p>
<ol>
<li>Первый пример предусматривает попытку распаковки слишком большого количества значений. В строке уведомлений говорится о том, где именно ожидается распаковка трех значений, но на выходе получаются только два.</li>
<li>Во втором примере программа пытается получить слишком много значений. Для распаковки их недостаточно.</li>
</ol>
<p>Все перечисленные исключения – это самые распространенные в Python. Они не являются исчерпывающими, но встречаются в разработке программного обеспечения чаще остальных.</p>
<p>Лучше разобраться с import traceback, а также рассмотреть другие ошибки при трассировке, помогут дистанционные онлайн-курсы. Они рассчитаны на широкую публику и могут быть подобраны в зависимости от первоначальных знаний разработчика. В срок до 12 месяцев пользователь сможет освоить любое IT-направление и подтвердить обучение электронным сертификатом.</p>
<p>Интересует <a href="https://otus.ru/lessons/python-professional/?utm_source=oj&utm_medium=affilate&utm_campaign=python" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external" class="wpel-icon-right">Python<span class="wpel-icon wpel-image wpel-icon-6"></span></a>? Добро пожаловать на курс в Otus!</p>
</div><!-- .post-content -->
<div class="the-post-foot cf">
<div class="tag-share cf">
<div class="post-tags"><a href="https://otus.ru/journal/tag/python/" rel="tag" data-wpel-link="internal">Python</a></div>
<div class="post-share">
<div class="post-share-icons cf">
<span class="counters">
</span>
<a href="https://www.facebook.com/sharer.php?u=https%3A%2F%2Fotus.ru%2Fjournal%2Ftraceback-v-pitone%2F" class="link facebook wpel-icon-right" target="_blank" title="Share on Facebook" data-wpel-link="external" rel="nofollow external noopener noreferrer"><i class="fa fa-facebook"></i><span class="wpel-icon wpel-image wpel-icon-6"></span></a>
<a href="https://twitter.com/intent/tweet?url=https%3A%2F%2Fotus.ru%2Fjournal%2Ftraceback-v-pitone%2F&text=Traceback%20%D0%B2%20%D0%9F%D0%B8%D1%82%D0%BE%D0%BD%D0%B5" class="link twitter wpel-icon-right" target="_blank" title="Share on Twitter" data-wpel-link="external" rel="nofollow external noopener noreferrer"><i class="fa fa-twitter"></i><span class="wpel-icon wpel-image wpel-icon-6"></span></a>
<a href="https://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Fotus.ru%2Fjournal%2Ftraceback-v-pitone%2F" class="link linkedin wpel-icon-right" target="_blank" title="LinkedIn" data-wpel-link="external" rel="nofollow external noopener noreferrer"><i class="fa fa-linkedin"></i><span class="wpel-icon wpel-image wpel-icon-6"></span></a>
<a href="https://pinterest.com/pin/create/button/?url=https%3A%2F%2Fotus.ru%2Fjournal%2Ftraceback-v-pitone%2F&media=https%3A%2F%2Fotus.ru%2Fjournal%2Fwp-content%2Fuploads%2F2023%2F06%2Foj-1080x72057-1.jpg&description=Traceback%20%D0%B2%20%D0%9F%D0%B8%D1%82%D0%BE%D0%BD%D0%B5" class="link pinterest wpel-icon-right" target="_blank" title="Pinterest" data-wpel-link="external" rel="nofollow external noopener noreferrer"><i class="fa fa-pinterest-p"></i><span class="wpel-icon wpel-image wpel-icon-6"></span></a>
</div>
</div>
</div>
</div>
<div class="post-nav">
<div class="post previous cf">
<a href="https://otus.ru/journal/regulyarnye-vyrazheniya/" title="Prev Post" class="nav-icon" data-wpel-link="internal">
<i class="fa fa-angle-left"></i>
</a>
<span class="content">
<a href="https://otus.ru/journal/regulyarnye-vyrazheniya/" class="image-link" rel="previous" data-wpel-link="internal">
<img width="150" height="106" src="data:image/svg+xml,%3Csvg%20viewBox%3D%270%200%20150%20106%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%3C%2Fsvg%3E" class="attachment-thumbnail size-thumbnail lazyload wp-post-image" alt="Регулярные выражения" decoding="async" loading="lazy" data-srcset="https://otus.ru/journal/wp-content/uploads/2023/06/oj-1080x72056-1-150x106.jpg 150w, https://otus.ru/journal/wp-content/uploads/2023/06/oj-1080x72056-1-300x212.jpg 300w, https://otus.ru/journal/wp-content/uploads/2023/06/oj-1080x72056-1-1024x724.jpg 1024w, https://otus.ru/journal/wp-content/uploads/2023/06/oj-1080x72056-1-768x543.jpg 768w, https://otus.ru/journal/wp-content/uploads/2023/06/oj-1080x72056-1-1536x1086.jpg 1536w" data-src="https://otus.ru/journal/wp-content/uploads/2023/06/oj-1080x72056-1-150x106.jpg" data-sizes="(max-width: 150px) 100vw, 150px" title="Регулярные выражения" /> </a>
<div class="post-meta">
<span class="label">Prev Post</span>
<div class="post-meta post-meta-b">
<h2 class="post-title">
<a href="https://otus.ru/journal/regulyarnye-vyrazheniya/" data-wpel-link="internal">Регулярные выражения</a>
</h2>
<div class="below">
<a href="https://otus.ru/journal/regulyarnye-vyrazheniya/" class="meta-item date-link" data-wpel-link="internal"><time class="post-date" datetime="2023-06-05T21:00:25+00:00">5 июня, 2023</time></a>
<span class="meta-sep"></span>
<span class="meta-item read-time">9 Mins Read</span>
</div>
</div> </div>
</span>
</div>
<div class="post next cf">
<a href="https://otus.ru/journal/cikly-v-c-i-c/" title="Next Post" class="nav-icon" data-wpel-link="internal">
<i class="fa fa-angle-right"></i>
</a>
<span class="content">
<a href="https://otus.ru/journal/cikly-v-c-i-c/" class="image-link" rel="next" data-wpel-link="internal">
<img width="150" height="106" src="data:image/svg+xml,%3Csvg%20viewBox%3D%270%200%20150%20106%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%3C%2Fsvg%3E" class="attachment-thumbnail size-thumbnail lazyload wp-post-image" alt="Циклы в C++ и C" decoding="async" loading="lazy" data-srcset="https://otus.ru/journal/wp-content/uploads/2023/06/oj-1080x72058-1-150x106.jpg 150w, https://otus.ru/journal/wp-content/uploads/2023/06/oj-1080x72058-1-300x212.jpg 300w, https://otus.ru/journal/wp-content/uploads/2023/06/oj-1080x72058-1-1024x724.jpg 1024w, https://otus.ru/journal/wp-content/uploads/2023/06/oj-1080x72058-1-768x543.jpg 768w, https://otus.ru/journal/wp-content/uploads/2023/06/oj-1080x72058-1-1536x1086.jpg 1536w" data-src="https://otus.ru/journal/wp-content/uploads/2023/06/oj-1080x72058-1-150x106.jpg" data-sizes="(max-width: 150px) 100vw, 150px" title="Циклы в C++ и C" /> </a>
<div class="post-meta">
<span class="label">Next Post</span>
<div class="post-meta post-meta-b">
<h2 class="post-title">
<a href="https://otus.ru/journal/cikly-v-c-i-c/" data-wpel-link="internal">Циклы в C++ и C</a>
</h2>
<div class="below">
<a href="https://otus.ru/journal/cikly-v-c-i-c/" class="meta-item date-link" data-wpel-link="internal"><time class="post-date" datetime="2023-06-06T16:00:14+00:00">6 июня, 2023</time></a>
<span class="meta-sep"></span>
<span class="meta-item read-time">5 Mins Read</span>
</div>
</div> </div>
</span>
</div>
</div>
<section class="related-posts grid-3">
<h4 class="section-head"><span class="title">Читать ещё</span></h4>
<div class="ts-row posts cf">
<article class="post col-4">
<a href="https://otus.ru/journal/uroven-gotovnosti-cto-k-2026/" title="Уровень готовности CTO к 2026" class="image-link" data-wpel-link="internal">
<img width="270" height="180" src="data:image/svg+xml,%3Csvg%20viewBox%3D%270%200%20270%20180%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%3C%2Fsvg%3E" class="image lazyload wp-post-image" alt="Уровень готовности CTO к 2026" title="Уровень готовности CTO к 2026" decoding="async" loading="lazy" data-srcset="https://otus.ru/journal/wp-content/uploads/2025/11/oj-1080x720-kopiya-3-270x180.jpg 270w, https://otus.ru/journal/wp-content/uploads/2025/11/oj-1080x720-kopiya-3-770x515.jpg 770w, https://otus.ru/journal/wp-content/uploads/2025/11/oj-1080x720-kopiya-3-370x245.jpg 370w" data-src="https://otus.ru/journal/wp-content/uploads/2025/11/oj-1080x720-kopiya-3-270x180.jpg" data-sizes="(max-width: 270px) 100vw, 270px" /> </a>
<div class="content">
<h3 class="post-title"><a href="https://otus.ru/journal/uroven-gotovnosti-cto-k-2026/" class="post-link" data-wpel-link="internal">Уровень готовности CTO к 2026</a></h3>
<div class="post-meta">
<time class="post-date" datetime="2025-11-16T19:50:59+00:00">16 ноября, 2025</time>
</div>
</div>
</article >
<article class="post col-4">
<a href="https://otus.ru/journal/novye-uroki-noyabrya-tolko-top-temy-po-programmirovaniju/" title="Новые уроки ноября: только топ-темы по программированию" class="image-link" data-wpel-link="internal">
<img width="270" height="180" src="data:image/svg+xml,%3Csvg%20viewBox%3D%270%200%20270%20180%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%3C%2Fsvg%3E" class="image lazyload wp-post-image" alt="Новые уроки ноября: только топ-темы по программированию" title="Новые уроки ноября: только топ-темы по программированию" decoding="async" loading="lazy" data-srcset="https://otus.ru/journal/wp-content/uploads/2025/11/oj-1080x720-kopiya-2-270x180.jpg 270w, https://otus.ru/journal/wp-content/uploads/2025/11/oj-1080x720-kopiya-2-770x515.jpg 770w, https://otus.ru/journal/wp-content/uploads/2025/11/oj-1080x720-kopiya-2-370x245.jpg 370w" data-src="https://otus.ru/journal/wp-content/uploads/2025/11/oj-1080x720-kopiya-2-270x180.jpg" data-sizes="(max-width: 270px) 100vw, 270px" /> </a>
<div class="content">
<h3 class="post-title"><a href="https://otus.ru/journal/novye-uroki-noyabrya-tolko-top-temy-po-programmirovaniju/" class="post-link" data-wpel-link="internal">Новые уроки ноября: только топ-темы по программированию</a></h3>
<div class="post-meta">
<time class="post-date" datetime="2025-11-09T23:24:11+00:00">9 ноября, 2025</time>
</div>
</div>
</article >
<article class="post col-4">
<a href="https://otus.ru/journal/schjot-idjot-na-chasy/" title="Счёт идёт на часы" class="image-link" data-wpel-link="internal">
<img width="270" height="180" src="data:image/svg+xml,%3Csvg%20viewBox%3D%270%200%20270%20180%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%3C%2Fsvg%3E" class="image lazyload wp-post-image" alt="Счёт идёт на часы" title="Счёт идёт на часы" decoding="async" loading="lazy" data-srcset="https://otus.ru/journal/wp-content/uploads/2025/10/oj-1080x720-kopiya-7-270x180.png 270w, https://otus.ru/journal/wp-content/uploads/2025/10/oj-1080x720-kopiya-7-770x515.png 770w, https://otus.ru/journal/wp-content/uploads/2025/10/oj-1080x720-kopiya-7-370x245.png 370w" data-src="https://otus.ru/journal/wp-content/uploads/2025/10/oj-1080x720-kopiya-7-270x180.png" data-sizes="(max-width: 270px) 100vw, 270px" /> </a>
<div class="content">
<h3 class="post-title"><a href="https://otus.ru/journal/schjot-idjot-na-chasy/" class="post-link" data-wpel-link="internal">Счёт идёт на часы</a></h3>
<div class="post-meta">
<time class="post-date" datetime="2025-10-30T15:04:59+00:00">30 октября, 2025</time>
</div>
</div>
</article >
</div>
</section>
</article> <!-- .the-post -->
</div>
<aside class="col-4 sidebar">
<div class="inner">
<ul>
<li id="search-2" class="widget widget_search"><h5 class="widget-title"><span>Поиск по блогу</span></h5>
<form method="get" class="search-form" action="https://otus.ru/journal/">
<label>
<span class="screen-reader-text">Search for:</span>
<input type="search" class="search-field" placeholder="Введите запрос и нажмите Enter" value="" name="s" title="Search for:" />
</label>
<button type="submit" class="search-submit"><i class="fa fa-search"></i></button>
</form>
</li>
<li id="tag_cloud-5" class="widget widget_tag_cloud"><h5 class="widget-title"><span>Метки</span></h5><div class="tagcloud"><a href="https://otus.ru/journal/tag/android-2/" class="tag-cloud-link tag-link-74 tag-link-position-1" style="font-size: 12.472222222222pt;" aria-label="Android (34 элемента)" data-wpel-link="internal">Android</a>
<a href="https://otus.ru/journal/tag/c-3/" class="tag-cloud-link tag-link-91 tag-link-position-2" style="font-size: 10.916666666667pt;" aria-label="C (23 элемента)" data-wpel-link="internal">C</a>
<a href="https://otus.ru/journal/tag/c-2/" class="tag-cloud-link tag-link-81 tag-link-position-3" style="font-size: 12.666666666667pt;" aria-label="C# (35 элементов)" data-wpel-link="internal">C#</a>
<a href="https://otus.ru/journal/tag/c/" class="tag-cloud-link tag-link-20 tag-link-position-4" style="font-size: 12.472222222222pt;" aria-label="c++ (34 элемента)" data-wpel-link="internal">c++</a>
<a href="https://otus.ru/journal/tag/computer-science/" class="tag-cloud-link tag-link-209 tag-link-position-5" style="font-size: 15.972222222222pt;" aria-label="computer science (78 элементов)" data-wpel-link="internal">computer science</a>
<a href="https://otus.ru/journal/tag/css/" class="tag-cloud-link tag-link-288 tag-link-position-6" style="font-size: 8.6805555555556pt;" aria-label="CSS (13 элементов)" data-wpel-link="internal">CSS</a>
<a href="https://otus.ru/journal/tag/data-science/" class="tag-cloud-link tag-link-151 tag-link-position-7" style="font-size: 8pt;" aria-label="Data Science (11 элементов)" data-wpel-link="internal">Data Science</a>
<a href="https://otus.ru/journal/tag/devops/" class="tag-cloud-link tag-link-98 tag-link-position-8" style="font-size: 10.138888888889pt;" aria-label="devops (19 элементов)" data-wpel-link="internal">devops</a>
<a href="https://otus.ru/journal/tag/docker/" class="tag-cloud-link tag-link-143 tag-link-position-9" style="font-size: 8.2916666666667pt;" aria-label="Docker (12 элементов)" data-wpel-link="internal">Docker</a>
<a href="https://otus.ru/journal/tag/gamedev/" class="tag-cloud-link tag-link-25 tag-link-position-10" style="font-size: 11.694444444444pt;" aria-label="gamedev (28 элементов)" data-wpel-link="internal">gamedev</a>
<a href="https://otus.ru/journal/tag/hr/" class="tag-cloud-link tag-link-103 tag-link-position-11" style="font-size: 8pt;" aria-label="hr (11 элементов)" data-wpel-link="internal">hr</a>
<a href="https://otus.ru/journal/tag/html/" class="tag-cloud-link tag-link-217 tag-link-position-12" style="font-size: 11.208333333333pt;" aria-label="HTML (25 элементов)" data-wpel-link="internal">HTML</a>
<a href="https://otus.ru/journal/tag/ios/" class="tag-cloud-link tag-link-101 tag-link-position-13" style="font-size: 8.9722222222222pt;" aria-label="iOS (14 элементов)" data-wpel-link="internal">iOS</a>
<a href="https://otus.ru/journal/tag/it/" class="tag-cloud-link tag-link-50 tag-link-position-14" style="font-size: 10.527777777778pt;" aria-label="IT (21 элемент)" data-wpel-link="internal">IT</a>
<a href="https://otus.ru/journal/tag/java/" class="tag-cloud-link tag-link-75 tag-link-position-15" style="font-size: 15.680555555556pt;" aria-label="Java (73 элемента)" data-wpel-link="internal">Java</a>
<a href="https://otus.ru/journal/tag/javascript/" class="tag-cloud-link tag-link-83 tag-link-position-16" style="font-size: 14.319444444444pt;" aria-label="JavaScript (53 элемента)" data-wpel-link="internal">JavaScript</a>
<a href="https://otus.ru/journal/tag/linux/" class="tag-cloud-link tag-link-141 tag-link-position-17" style="font-size: 11.888888888889pt;" aria-label="Linux (29 элементов)" data-wpel-link="internal">Linux</a>
<a href="https://otus.ru/journal/tag/machine-learning/" class="tag-cloud-link tag-link-167 tag-link-position-18" style="font-size: 8.6805555555556pt;" aria-label="Machine Learning (13 элементов)" data-wpel-link="internal">Machine Learning</a>
<a href="https://otus.ru/journal/tag/otus-book/" class="tag-cloud-link tag-link-261 tag-link-position-19" style="font-size: 9.9444444444444pt;" aria-label="otus book (18 элементов)" data-wpel-link="internal">otus book</a>
<a href="https://otus.ru/journal/tag/php/" class="tag-cloud-link tag-link-45 tag-link-position-20" style="font-size: 10.527777777778pt;" aria-label="PHP (21 элемент)" data-wpel-link="internal">PHP</a>
<a href="https://otus.ru/journal/tag/python/" class="tag-cloud-link tag-link-27 tag-link-position-21" style="font-size: 16.944444444444pt;" aria-label="Python (99 элементов)" data-wpel-link="internal">Python</a>
<a href="https://otus.ru/journal/tag/qa/" class="tag-cloud-link tag-link-155 tag-link-position-22" style="font-size: 11.402777777778pt;" aria-label="qa (26 элементов)" data-wpel-link="internal">qa</a>
<a href="https://otus.ru/journal/tag/sql/" class="tag-cloud-link tag-link-38 tag-link-position-23" style="font-size: 12.861111111111pt;" aria-label="SQL (37 элементов)" data-wpel-link="internal">SQL</a>
<a href="https://otus.ru/journal/tag/team-lead/" class="tag-cloud-link tag-link-364 tag-link-position-24" style="font-size: 9.9444444444444pt;" aria-label="team lead (18 элементов)" data-wpel-link="internal">team lead</a>
<a href="https://otus.ru/journal/tag/unity/" class="tag-cloud-link tag-link-24 tag-link-position-25" style="font-size: 8pt;" aria-label="unity (11 элементов)" data-wpel-link="internal">unity</a>
<a href="https://otus.ru/journal/tag/algoritmy/" class="tag-cloud-link tag-link-30 tag-link-position-26" style="font-size: 9.9444444444444pt;" aria-label="Алгоритмы (18 элементов)" data-wpel-link="internal">Алгоритмы</a>
<a href="https://otus.ru/journal/tag/bazy-dannyh/" class="tag-cloud-link tag-link-40 tag-link-position-27" style="font-size: 10.138888888889pt;" aria-label="Базы данных (19 элементов)" data-wpel-link="internal">Базы данных</a>
<a href="https://otus.ru/journal/tag/matematika/" class="tag-cloud-link tag-link-44 tag-link-position-28" style="font-size: 10.916666666667pt;" aria-label="Математика (23 элемента)" data-wpel-link="internal">Математика</a>
<a href="https://otus.ru/journal/tag/arhitektura-po/" class="tag-cloud-link tag-link-10 tag-link-position-29" style="font-size: 9.4583333333333pt;" aria-label="архитектура ПО (16 элементов)" data-wpel-link="internal">архитектура ПО</a>
<a href="https://otus.ru/journal/tag/bazy-dannyh-2/" class="tag-cloud-link tag-link-251 tag-link-position-30" style="font-size: 10.138888888889pt;" aria-label="базы данных (19 элементов)" data-wpel-link="internal">базы данных</a>
<a href="https://otus.ru/journal/tag/vebinar/" class="tag-cloud-link tag-link-201 tag-link-position-31" style="font-size: 13.930555555556pt;" aria-label="вебинар (48 элементов)" data-wpel-link="internal">вебинар</a>
<a href="https://otus.ru/journal/tag/dajdzhest/" class="tag-cloud-link tag-link-308 tag-link-position-32" style="font-size: 10.722222222222pt;" aria-label="дайджест (22 элемента)" data-wpel-link="internal">дайджест</a>
<a href="https://otus.ru/journal/tag/zapis-vebinara/" class="tag-cloud-link tag-link-226 tag-link-position-33" style="font-size: 14.902777777778pt;" aria-label="запись вебинара (61 элемент)" data-wpel-link="internal">запись вебинара</a>
<a href="https://otus.ru/journal/tag/zapis-uroka/" class="tag-cloud-link tag-link-272 tag-link-position-34" style="font-size: 16.069444444444pt;" aria-label="запись урока (80 элементов)" data-wpel-link="internal">запись урока</a>
<a href="https://otus.ru/journal/tag/informacionnaya-bezopasnost/" class="tag-cloud-link tag-link-232 tag-link-position-35" style="font-size: 10.138888888889pt;" aria-label="информационная безопасность (19 элементов)" data-wpel-link="internal">информационная безопасность</a>
<a href="https://otus.ru/journal/tag/karera-v-it/" class="tag-cloud-link tag-link-292 tag-link-position-36" style="font-size: 9.9444444444444pt;" aria-label="карьера в IT (18 элементов)" data-wpel-link="internal">карьера в IT</a>
<a href="https://otus.ru/journal/tag/podborka/" class="tag-cloud-link tag-link-7 tag-link-position-37" style="font-size: 12.666666666667pt;" aria-label="подборка (35 элементов)" data-wpel-link="internal">подборка</a>
<a href="https://otus.ru/journal/tag/podborka-statej/" class="tag-cloud-link tag-link-219 tag-link-position-38" style="font-size: 15.777777777778pt;" aria-label="подборка статей (75 элементов)" data-wpel-link="internal">подборка статей</a>
<a href="https://otus.ru/journal/tag/programmirovanie/" class="tag-cloud-link tag-link-65 tag-link-position-39" style="font-size: 22pt;" aria-label="программирование (332 элемента)" data-wpel-link="internal">программирование</a>
<a href="https://otus.ru/journal/tag/proekt/" class="tag-cloud-link tag-link-321 tag-link-position-40" style="font-size: 11.888888888889pt;" aria-label="проект (29 элементов)" data-wpel-link="internal">проект</a>
<a href="https://otus.ru/journal/tag/proektnaya-rabota/" class="tag-cloud-link tag-link-310 tag-link-position-41" style="font-size: 11.597222222222pt;" aria-label="проектная работа (27 элементов)" data-wpel-link="internal">проектная работа</a>
<a href="https://otus.ru/journal/tag/seti/" class="tag-cloud-link tag-link-181 tag-link-position-42" style="font-size: 12.958333333333pt;" aria-label="сети (38 элементов)" data-wpel-link="internal">сети</a>
<a href="https://otus.ru/journal/tag/testirovanie/" class="tag-cloud-link tag-link-69 tag-link-position-43" style="font-size: 13.930555555556pt;" aria-label="тестирование (48 элементов)" data-wpel-link="internal">тестирование</a>
<a href="https://otus.ru/journal/tag/upravlenie-komandoj/" class="tag-cloud-link tag-link-63 tag-link-position-44" style="font-size: 11.694444444444pt;" aria-label="управление командой (28 элементов)" data-wpel-link="internal">управление командой</a>
<a href="https://otus.ru/journal/tag/habr-2/" class="tag-cloud-link tag-link-203 tag-link-position-45" style="font-size: 13.930555555556pt;" aria-label="хабр (48 элементов)" data-wpel-link="internal">хабр</a></div>
</li>
</ul>
</div>
</aside>
</div> <!-- .ts-row -->
</div> <!-- .main -->
<footer class="main-footer dark bold">
<section class="lower-footer cf">
<div class="wrap">
<div class="links">
<div class="menu-menju-navykov-container"><ul id="menu-menju-navykov-1" class="menu"><li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10413"><a href="https://otus.ru/categories/programming/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Программирование<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10414"><a href="https://otus.ru/categories/architecture/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Архитектура<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10415"><a href="https://otus.ru/categories/operations/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Инфраструктура<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10416"><a href="https://otus.ru/categories/information-security-courses/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Безопасность<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10417"><a href="https://otus.ru/categories/data-science/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Data Science<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10418"><a href="https://otus.ru/categories/gamedev/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">GameDev<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10419"><a href="https://otus.ru/categories/marketing-business/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Управление<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10420"><a href="https://otus.ru/categories/analytics/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Аналитика и анализ<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10421"><a href="https://otus.ru/categories/testing/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer" class="wpel-icon-right">Тестирование<span class="wpel-icon wpel-image wpel-icon-6"></span></a></li>
</ul></div> </div>
<p class="copyright"> © 2015-2026 OTUS </p>
<div class="to-top">
<a href="#" class="back-to-top"><i class="fa fa-angle-up"></i> Top</a>
</div>
</div>
</section>
</footer>
</div> <!-- .main-wrap -->
<div class="mobile-menu-container off-canvas" id="mobile-menu">
<a href="#" class="close"><i class="fa fa-times"></i></a>
<div class="logo">
</div>
<ul class="mobile-menu"></ul>
</div>
<div class="search-modal-wrap">
<div class="search-modal-box" role="dialog" aria-modal="true">
<form method="get" class="search-form" action="https://otus.ru/journal/">
<input type="search" class="search-field" name="s" placeholder="Search..." value="" required />
<button type="submit" class="search-submit visuallyhidden">Submit</button>
<p class="message">
Type above and press <em>Enter</em> to search. Press <em>Esc</em> to cancel. </p>
</form>
</div>
</div>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/plugins/clearfy/components/comments-plus/assets/js/url-span.js" id="wbcr-comments-plus-url-span-js"></script>
<script type="text/javascript" id="ez-toc-scroll-scriptjs-js-extra">
/* <![CDATA[ */
var eztoc_smooth_local = {"scroll_offset":"30"};
/* ]]> */
</script>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/plugins/easy-table-of-contents/assets/js/smooth_scroll.min.js" id="ez-toc-scroll-scriptjs-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/plugins/easy-table-of-contents/vendor/js-cookie/js.cookie.min.js" id="ez-toc-js-cookie-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/plugins/easy-table-of-contents/vendor/sticky-kit/jquery.sticky-kit.min.js" id="ez-toc-jquery-sticky-kit-js"></script>
<script type="text/javascript" id="ez-toc-js-js-extra">
/* <![CDATA[ */
var ezTOC = {"smooth_scroll":"1","visibility_hide_by_default":"","scroll_offset":"30","fallbackIcon":"<span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span>"};
/* ]]> */
</script>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/plugins/easy-table-of-contents/assets/js/front.min.js" id="ez-toc-js-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/themes/contentberg/js/custom-script.js" id="custom-script-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/themes/contentberg/js/magnific-popup.js" id="magnific-popup-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/themes/contentberg/js/jquery.fitvids.js" id="jquery-fitvids-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-includes/js/imagesloaded.min.js" id="imagesloaded-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/themes/contentberg/js/object-fit-images.js" id="object-fit-images-js"></script>
<script type="text/javascript" id="contentberg-theme-js-extra">
/* <![CDATA[ */
var Bunyad = {"custom_ajax_url":"\/journal\/traceback-v-pitone\/"};
/* ]]> */
</script>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/themes/contentberg/js/theme.js" id="contentberg-theme-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/themes/contentberg/js/theia-sticky-sidebar.js" id="theia-sticky-sidebar-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/themes/contentberg/js/jquery.slick.js" id="jquery-slick-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-content/themes/contentberg/js/jarallax.js" id="jarallax-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-includes/js/masonry.min.js" id="masonry-js"></script>
<script type="text/javascript" src="https://otus.ru/journal/wp-includes/js/jquery/jquery.masonry.min.js" id="jquery-masonry-js"></script>
</body>
</html>
<!-- Cache served by breeze CACHE - Last modified: Tue, 10 Mar 2026 09:01:49 GMT -->