Traceback python 3 как записать в файл

Обновлено: 02.07.2024

Python отображает трассировку (traceback) при возникновении исключения в вашем коде. Содержимое трассировки может быть немного запутанным, если вы видите ее впервые или не знаете, что в она означает. Но трассировка содержит множество информации, которая может помочь вам диагностировать и устранить причину возникновения исключения.

К концу этой статьи вы сможете:

  • Лучше разбираться с содержимом трассировки (traceback)
  • Сразу узнавать некоторые из наиболее распространенных шаблонов в трассировке
  • Узнаете как правильно логировать трассировку, в то же время обрабатывая исключение

Что такое Traceback в Python?

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

Здесь вызывается функция greet() с параметром someone. Однако в greet() это имя переменной не используется. Вместо этого было ошибочно указано переменная someon в вызове print().

Примечание. В этом руководстве предполагается, что вы знаете что такое исключения в Python. Если вы незнакомы или просто хотите освежиться, то вам следует почитать Python Exceptions: Введение.

Когда вы запустите эту программу, вы получите следующий traceback:

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

В последней строке в этом случае достаточно информации, чтобы помочь вам решить проблему. Поиск кода по имени someon, который является орфографической ошибкой, укажет вам правильное направление. Однако часто ваш код намного сложнее.

Как читать Traceback?

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

Обзор Traceback

Есть несколько разделов в каждой трассировки, которые по своему важны. Диаграмма ниже выделяет эти части:


В Python лучше читать трассировку снизу вверх:

Есть несколько различий между выводом трассировки, когда вы выполняете свой код в командной строке и выполняете код в REPL. Ниже приведен тот же код из предыдущего раздела, выполненного в REPL, и результирующий вывод трассировки:

Обратите внимание, что вместо имен файлов вы получаете <stdin>. Это имеет смысл, поскольку вы вводили код с помощью стандартного ввода. Кроме того, выполненные строки кода не отображаются в трассировке.

Пример чтения трассировки

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

Приведенный ниже код используется в следующих примерах для иллюстрации информации, которую предоставляет вам трассировка:

Здесь who_to_greet() принимает значение person и либо возвращает его, либо запрашивает возвращаемое значение.

Затем greet() принимает имя, которое нужно приветствовать, someone, и необязательное значение greeting и вызывает print(). who_to_greet() также вызывается с переданным значением someone.

Наконец, greet_many() будет перебирать список people и вызывать greet(). Если при вызове greet() возникает исключение, то выводится простое резервное приветствие.

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

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

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

С другим файлом и другим вводом вы можете увидеть, что трассировка действительно указывает вам правильное направление, чтобы найти проблему. Если вы следуете дальше, удалите глючный вызов greet() из нижней части greetings.py и добавьте новый файл example.py со следующим содержимым:

В этом файле вы импортируете ваш предыдущий модуль, greetings.py, и использует из него greet(). Вот что произойдет, если вы запустите example.py:

Двигаясь вверх, вы видите строку кода, которая была выполнена. Затем файл и номер строки кода. Однако на этот раз вместо <module> мы получаем имя функции, которая выполнялась, greet().

Переходя к следующей исполняемой строке кода, мы видим, что наш проблемный вызов greet() передается в виде целого числа.

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

Так как это может немного сбить с толку, рассмотрим пример. Добавьте вызов greet_many() в конец greetings.py:

Это должно привести к выводу приветствия всем трем людям. Однако, если вы запустите этот код, вы увидите пример вывода нескольких трассировок:

Примечание. Функция отображения обратных трассировок предыдущих исключений была добавлена в Python 3. В Python 2 вы получите только трассировку последнего исключения.

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

Еще раз повторим соответствующую часть greetings.py:

Поэтому, когда greet() приводит к TypeError из-за неправильного целочисленного ввода, greet_many() обрабатывает это исключение и пытается вывести простое приветствие. Здесь код заканчивается в результате другого, похожего, исключения. Он все еще пытается добавить строку и целое число.

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

Каковы некоторые общие трассировки в Python?

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

Далее рассмотрим некоторые распространенные исключения, с которыми вы можете столкнуться.

AttributeError

AttributeError вызывается, когда вы пытаетесь получить доступ к атрибуту объекта, для которого этот атрибут не определен.

Возникает при сбое ссылки на атрибут или при операции присвоения. (Источник)

Вот пример возникновения AttributeError:

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

В приведенном выше примере вы можете ожидать, что a_list будет иметь тип list, у которого есть метод с именем .append(). Когда вы получаете исключение AttributeError и видите, что оно было сгенерировано, когда вы попытались вызвать .append(), это говорит о том, что вы, вероятно, не имеете дело с ожидаемым типом объекта.

ImportError

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

Вот пример возникновения ImportError и ModuleNotFoundError:

IndexError

Ошибка IndexError возникает, когда вы пытаетесь получить индекс из последовательности, такой как список или кортеж, а индекс не найден в этой последовательности.

Возникает, когда текущий индекс последовательности находится вне используемого диапазона. (Источник)

Вот пример, который вызывает IndexError:

KeyError

Подобно IndexError, KeyError вызывается, когда вы пытаетесь получить доступ к ключу, которого нет в объекте, обычно это dict. Думайте об этом как об IndexError, но для словарей.

Возникает, когда ключ набора (словарь) не найден в наборе существующих ключей. (Источник)

Вот пример возникновения KeyError:

Для более глубокого понимания KeyError, взгляните на Python KeyError Exceptions and How to Handle Them..

NameError

Ошибка NameError возникает, когда вы ссылаетесь на переменную, модуль, класс, функцию или другое имя, которое не было определено в вашем коде.

Возникает, когда локальное или глобальное имя не найдено. (Источник)

В приведенном ниже коде greet() принимает параметр person. Но в самой функции этот параметр был ошибочно указан как persn:

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

SyntaxError

Ошибка SyntaxError возникает, когда в вашем коде неверный синтаксис Python.

Возникает, когда синтаксический анализатор обнаруживает синтаксическую ошибку. (Источник)

Ниже проблема заключается в отсутствующем двоеточии, которое должно находиться в конце строки определения функции. В Python REPL эта синтаксическая ошибка возникает сразу после нажатия Enter:

Кроме того, при трассировке SyntaxError обычная трассировка последней строки отсутствует. Это связано с тем, что ошибка SyntaxError возникает, когда Python пытается проанализировать ваш код, а строки фактически не выполняются.

TypeError

Ошибка TypeError возникает, когда ваш код пытается что-то сделать с объектом, который не может этого сделать, например, пытается добавить строку к целому числу или вызывать len() для объекта, длина которого не определена.

Возникает, когда операция или функция применяется к объекту неподходящего типа. (Источник)

Ниже приведено несколько примеров возникновения TypeError:

Первые два примера пытаются добавить строки и целые числа вместе. Тем не менее, они немного отличаются:

ValueError

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

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

Вот два примера создания ValueError:

Как логировать трассировку?

Вот более реальный пример кода, который должен скрыть некоторые трассировки Python. В этом примере используется библиотека requests . Вы можете узнать больше о ней в Python’s Requests Library (Guide):

Однако иногда URL-адрес, который выдается для извлечения сценарием, не существует или хост-сервер будет не работать. В этих случаях этот сценарий теперь вызовет необработанное исключение ConnectionError и отобразит трассировку:

Трассировка Python здесь может быть очень длинной со многими другими исключениями, которые в конечном итоге приводят к тому, что ConnectionError вызывается самими запросами. Если вы переместитесь вверх по трассировке окончательных исключений, вы увидите, что проблема началась в нашем коде со строки 5 urlcaller.py.

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

Приведенный выше код использует оператор else с блоком try и except. Если вы не знакомы с этой функцией Python, ознакомьтесь с разделом else Python Exceptions: An Introduction.

Теперь, когда вы запустите сценарий с URL-адресом, который приведет к возникновению ошибки ConnectionError, вы получите вывод -1 для кода состояния и строку Connection Error:

Примечание: Чтобы узнать больше о системе журналирования Python, ознакомьтесь со статьей Логирование в Python (Logging in Python).

Вы можете зарегистрировать трассировку в сценарии, импортировав пакет logging, получив регистратор и вызвав .exception() для этого регистратора в блоке except блока try/except. Ваш финальный скрипт должен выглядеть примерно так:

Теперь, когда вы запустите сценарий для проблемного URL, он выведет ожидаемое -1 и Connection Error, но также запишет трассировку в лог:

Заключение

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

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

Модуль предоставляет стандартный интерфейс для извлечения, форматирования и печати трассировки стека Python программ. Он точно имитирует поведение Python интерпретатора при печати трассировки стека. Это полезно при необходимости печати трасс стека под управлением программы, например, в «обертке» вокруг интерпретатор.

Модуль использует объекты трейсбэк — это тип объекта, который хранится в переменной sys.last_traceback и возвращенный в качестве третьего элемента из sys.exc_info() .

Модуль определяет следующие функции:

traceback. print_tb ( tb, limit=None, file=None ) ¶

Печать до limit записей трассировки стека из объекта трассировки tb (начиная с кадра вызывающего), если limit положительный. В противном случае напечатает последние записи abs(limit) . Если limit пропущено или None , печатаются все записи. Если file опущен или None , выходной сигнал переходит в sys.stderr ; в противном случае это должен быть открытый файл или похожий на файл объект для получения выходных данных.

Изменено в версии 3.5: Добавлена отрицательная поддержка limit.

traceback. print_exception ( etype, value, tb, limit=None, file=None, chain=True ) ¶

Печать информации об исключениях и записей трассировки стека из объекта трейсбэка tb в file. Это отличается от print_tb() следующими способами:

  • если tb не None , он печатает Traceback (most recent call last): заголовка
  • он печатает etype исключения и value после трассировки стека
  • если type(value)SyntaxError и value имеет соответствующий формат, он печатает строку, в которой произошла синтаксическая ошибка, с помощью вставки, указывающей приблизительное положение ошибки.

У дополнительного аргумента limit есть то же значение что касается print_tb() . Если chain будет верен (дефолт), то цепочечные исключения ( __cause__ или __context__ атрибуты исключения) будут напечатаны также, как сам интерпретатор делает, печатая необработанное исключение.

Изменено в версии 3.5: Аргумент etype игнорируется и выводится из типа value.

Это стенография для print_exception(*sys.exc_info(), limit, file, chain) .

traceback. print_last ( limit=None, file=None, chain=True ) ¶

Это стенография для print_exception(sys.last_type, sys.last_value, sys.last_traceback, limit, file, chain) . В общем случае он будет работать только после того, как исключение достигнет интерактивного запроса (см. sys.last_type ).

traceback. print_stack ( f=None, limit=None, file=None ) ¶

При положительном limit распечатать до limit записей трассировки стека (начиная с точки вызова). В противном случае напечатать последние записи abs(limit) . Если limit пропущено или None , печатаются все записи. Необязательный аргумент f можно используемый, чтобы указать альтернативный фрейм стека для запуска. Необязательный аргумент file имеет то же значение, что и для print_tb() .

Изменено в версии 3.5: Добавлена отрицательная поддержка limit.

Возвращает объект StackSummary , представляющий список «предварительно обработанных» записей трассировки стека, извлеченных из объекта трейсбэк tb. Он полезен для альтернативного форматирования трасс стека. Необязательный аргумент limit имеет то же значение, что и для print_tb() . «Предварительно обработанная» запись трассировки стека - это объект FrameSummary , содержащий атрибуты filename , lineno , name и line , представляющий информацию, которая обычно печатается для трассировки стека. line представляет собой строка с разделенным начальным и конечным пробелами; если источник недоступен, он None .

traceback. extract_stack ( f=None, limit=None ) ¶

Извлеч необработанный трейсбэк из текущего фрейм стека. Формат возвращает значение совпадает с форматом extract_tb() . Необязательные аргументы f и limit имеют то же значение, что и для print_stack() .

traceback. format_list ( extracted_list ) ¶

Учитывая список кортежей или FrameSummary объектов, возвращенный extract_tb() или extract_stack() , возвращает список строки, готовых к печати. Каждый строка в результирующем списке соответствует элементу с одинаковым индексом в списке аргументов. Каждый строка заканчивается новой строкой; строки также может содержать внутренние новые строки для тех элементов, исходная текстовая строка которых не None .

traceback. format_exception_only ( etype, value ) ¶

traceback. format_exception ( etype, value, tb, limit=None, chain=True ) ¶

Отформатировать трассировку стека и сведения об исключении. Аргументы имеют то же значение, что и соответствующие аргументы для print_exception() . возвращает значение представляет собой список строки, каждый из которых оканчивается на новую строку, а некоторые содержат внутренние новые строки. При объединении и печати этих строк печатается точно такой же текст, как и print_exception() .

Изменено в версии 3.5: Аргумент etype игнорируется и выводится из типа value.

Это как print_exc(limit) , но возвращает строку вместо печати в файл.

traceback. format_tb ( tb, limit=None ) ¶

Стенограмма для format_list(extract_tb(tb, limit)) .

traceback. format_stack ( f=None, limit=None ) ¶

Стенограмма для format_list(extract_stack(f, limit)) .

traceback. clear_frames ( tb ) ¶

Очищает переменные локальная всех стековых кадров в трейсбэк tb путем вызова метода clear() каждого объекта фрейм.

Добавлено в версии 3.4.

Выполните обход стека после f.f_back из заданного фрейм, выдав фрейм и номер строки для каждого фрейм. Если f None , текущий стек будет используемый. Этот помощник используемый с StackSummary.extract() .

Добавлено в версии 3.5.

Выполнить обход следующего трейсбэк tb_next получая фрейм и номер линии для каждого фрейм. Этот помощник используемый с StackSummary.extract() .

Добавлено в версии 3.5.

Модуль также определяет следующие классы:

Объекты TracebackException ¶

Добавлено в версии 3.5.

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

class traceback. TracebackException ( exc_type, exc_value, exc_traceback, *, limit=None, lookup_lines=True, capture_locals=False ) ¶

Зафиксировать исключение для последующей визуализации. limit, lookup_lines и capture_locals как для класса StackSummary .

Отметим, что при захвате местных жителей они также показываются в трейсбэк.

Этот __suppress_context__ значение от исходной особой ситуации.

Класс исходного трейсбэк.

Для синтаксических ошибок - имя файла, в котором произошла ошибка.

Для синтаксических ошибок - номер строки, в которой произошла ошибка.

Для синтаксических ошибок - текст, в котором произошла ошибка.

Для синтаксических ошибок - смещение в текст, где произошла ошибка.

classmethod from_exception ( exc, *, limit=None, lookup_lines=True, capture_locals=False ) ¶

Зафиксировать исключение для последующей визуализации. limit, lookup_lines и capture_locals как для класса StackSummary .

Отметим, что при захвате местных жителей они также показываются в трейсбэк.

Если chain не True , __cause__ и __context__ не будут отформатированы.

Возвращает значение - это генератор строки, каждая из которых оканчивается на newline, а некоторые содержат внутренние newlines. print_exception() является оберткой вокруг этого метода, которая просто печатает строки в файл.

Отформатировать часть исключения трейсбэк.

Возвращает значение - это генератор строки, каждая из которых заканчивается новой строкой.

Обычно генератор испускает один строка; однако для SyntaxError исключений он выдает несколько строк, которые (при печати) отображают подробную информацию о том, где произошла синтаксическая ошибка.

Объекты StackSummary ¶

Добавлено в версии 3.5.

StackSummary объекты представляют стек вызовов, готовый к форматированию.

class traceback. StackSummary ¶ classmethod extract ( frame_gen, *, limit=None, lookup_lines=True, capture_locals=False ) ¶

Создать объект StackSummary из фрейм генератор (например, возвращенный walk_stack() или walk_tb() ).

При наличии limit из frame_gen берется только это количество кадров. Если lookup_lines - False , объекты возвращенный FrameSummary еще не будут читать свои линии в, делая стоимость создания более дешевого StackSummary (который может быть ценным, если это не может на самом деле быть отформатировано). Если capture_locals True переменные локальная в каждом FrameSummary захватываются как представления объектов.

classmethod from_list ( a_list ) ¶

Создать StackSummary объект из предоставленного списка FrameSummary объектов или старого списка кортежей. Каждый кортеж должен быть 4 кортежем с именем файла, lineno, именем, линией в качестве элементов.

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

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

Изменено в версии 3.6: Длинные последовательности повторяющихся кадров теперь сокращены.

Объекты FrameSummary ¶

Добавлено в версии 3.5.

FrameSummary объекты представляют один фрейм в трейсбэк.

class traceback. FrameSummary ( filename, lineno, name, lookup_line=True, locals=None, line=None ) ¶

Представляет один фрейм в трейсбэк или стеке, который форматируется или печатается. Он может дополнительно иметь строгую версию локальных кадров, включенных в него. Если lookup_line - False , у источника, код не смотрят вплоть до FrameSummary , есть line атрибут, к которому получают доступ (который также происходит, бросая его к кортежу). line могут быть предоставлены напрямую, и это предотвратит поиск линий вообще. locals является необязательным словарем переменных локальная, и если оно предоставляется, представления переменных сохраняются в сводке для последующего отображения.

Примеры Traceback¶

В этом простом примере реализован базовый цикл чтения-оценки-печати, аналогичный (но менее полезный, чем) стандартному Python интерактивному циклу интерпретатор. Для более полной реализации цикла интерпретатор обратитесь к модулю code .:

В следующем примере показаны различные способы печати и форматирования исключения и трейсбэк:

Выходные данные примера выглядят следующим образом:

В следующем примере показаны различные способы печати и форматирования стека:

Последний пример демонстрирует последние несколько функций форматирования:


Содержание статьи

Понимание того, какую информацию предоставляет traceback Python является основополагающим критерием того, как стать лучшим Python программистом.

К концу данной статьи вы сможете:

Есть вопросы по Python?

На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!

Telegram Чат & Канал

Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!

Паблик VK

Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!

Traceback называют по разному, иногда они упоминаются как трассировка стэка, обратная трассировка, и так далее. В Python используется определение “трассировка”.

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

Здесь say_hello() вызывается с параметром man . Однако, в say_hello() это имя переменной не используется. Это связано с тем, что оно написано по другому: wrong_variable в вызове print() .

Обратите внимание: в данной статье подразумевается, что вы уже имеете представление об ошибках Python. Если это вам не знакомо, или вы хотите освежить память, можете ознакомиться с нашей статьей: Обработка ошибок в Python

Когда вы запускаете эту программу, вы получите следующую трассировку:

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

В traceback выше, ошибкой является NameError, она означает, что есть отсылка к какому-то имени (переменной, функции, класса), которое не было определено. В данном случае, ссылаются на имя wrong_variable .

Последняя строка содержит достаточно информации для того, чтобы вы могли решить эту проблему. Поиск переменной wrong_variable , и заменит её атрибутом из функции на man . Однако, скорее всего в реальном случае вы будете иметь дело с более сложным кодом.

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

Подробный обзор структуры трассировки в Python 3

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

Обзор трассировки Python

В Python лучше всего читать трассировку снизу вверх.

Есть ряд отличий между выдачей трассировок, когда вы запускает код в командной строке, и между запуском кода в REPL. Ниже вы можете видеть тот же код из предыдущего раздела, запущенного в REPL и итоговой выдачей трассировки:

У меня очень большая программа на Python 3.x, работающая в Windows. Он отлично работает в 99,9% случаев, но иногда он падает. Я не уверен, что является причиной аварии, это может быть множество вещей. Из-за того, что мне нужно запустить программу «скомпилированный» .exe с невидимой консолью по соображениям безопасности (не спрашивайте), я не вижу никакой формы чтения консоли, когда она умирает. Поэтому, очевидно, было бы здорово, если бы я мог вместо этого выводить отслеживание сбоя в виде текстового файла.

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

3 ответа

Где-то в вашем коде у вас должна быть единственная точка входа в код, которая может быть сбойной (как минимум, в основном скрипте). Вы можете заключить это в пару try / except , а затем использовать функции из модуля traceback , чтобы напечатать исключение в файл, когда это произойдет:

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

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

Я закончил писать свою собственную функцию регистрации

Это требует time или datetime , я не уверен, какой. Также вам необходимо убедиться, что файл журнала существует.

Тогда я бы просто шлепнул его там, где мне нужно, например: logger(ERRLOG, "OCR didn't find poop. Check <>".format(ocr_outfilepath))

Например, если у меня есть очень надуманный пример скрипта Python, подобный этому

Который намеренно собирается вызвать исключение IndexError .

Вы можете запустить его так:

Который перенаправляет весь вывод и ошибки в файл.

Таким образом, вам не нужно ничего менять с помощью кода.

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