Ответ на этот вопрос зависит от версии Python, которую вы используете.
В Python 3
Все просто: исключения имеют __traceback__атрибут, содержащий трассировку. Этот атрибут также доступен для записи и может быть удобно установлен с помощью with_tracebackметода исключений:
raise Exception("foo occurred").with_traceback(tracebackobj)
Эти функции минимально описаны в raiseдокументации.
Вся заслуга в этой части ответа принадлежит Виктору, который первым опубликовал эту информацию . Я включаю его сюда только потому, что этот ответ застрял наверху, а Python 3 становится все более распространенным.
В Python 2
Это досадно сложно. Проблема с трассировкой заключается в том, что у них есть ссылки на кадры стека, а кадры стека имеют ссылки на трассировки, которые имеют ссылки на кадры стека, которые имеют ссылки на ... вы поняли. Это вызывает проблемы для сборщика мусора. (Спасибо ecatmur за первое указание на это.)
Хороший способ решить эту проблему - хирургическим путем разорвать цикл после выхода из exceptпредложения, что и делает Python 3. Решение Python 2 намного уродливее: вам предоставляется специальная функция sys.exc_info(), которая работает только внутри except предложения . Он возвращает кортеж, содержащий исключение, тип исключения и трассировку для любого исключения, которое в настоящее время обрабатывается.
Итак, если вы находитесь внутри exceptпредложения, вы можете использовать вывод sys.exc_info()вместе с tracebackмодулем для выполнения различных полезных вещей:
>>> import sys, traceback
>>> def raise_exception():
... try:
... raise Exception
... except Exception:
... ex_type, ex, tb = sys.exc_info()
... traceback.print_tb(tb)
... finally:
... del tb
...
>>> raise_exception()
File "<stdin>", line 3, in raise_exception
Но, как указывает ваше редактирование, вы пытаетесь получить трассировку, которая была бы напечатана, если бы ваше исключение не было обработано, после того, как оно уже было обработано. Это гораздо более сложный вопрос. К сожалению, sys.exc_infoвозвращается, (None, None, None)если исключение не обрабатывается. Другие связанные sysатрибуты тоже не помогают. sys.exc_tracebackустарел и не определен, если исключение не обрабатывается; sys.last_tracebackкажется идеальным, но, похоже, он определяется только во время интерактивных сеансов.
Если вы можете контролировать, как возникает исключение, вы можете использовать inspectи настраиваемое исключение для хранения некоторой информации. Но я не совсем уверен, как это сработает.
По правде говоря, перехват и возврат исключения - дело необычное. Это может быть признаком того, что вам все равно нужно провести рефакторинг.