Odpowiedź na to pytanie zależy od używanej wersji Pythona.
W Pythonie 3
To proste: wyjątki są wyposażone w __traceback__atrybut zawierający dane śledzenia. Ten atrybut jest również zapisywalny i można go wygodnie ustawić za pomocą with_tracebackmetody wyjątków:
raise Exception("foo occurred").with_traceback(tracebackobj)
Te funkcje są minimalnie opisane jako część raisedokumentacji.
Cała zasługa tej części odpowiedzi należy się Vyctorowi, który jako pierwszy opublikował te informacje . Uwzględniam to tutaj tylko dlatego, że ta odpowiedź utknęła na górze, a Python 3 staje się coraz bardziej powszechny.
W Pythonie 2
To irytująco złożone. Problem z trackbackami polega na tym, że mają one odniesienia do ramek stosu, a ramki stosu mają odniesienia do elementów traceback, które mają odniesienia do ramek stosu, które mają odniesienia do ... rozumiesz. Powoduje to problemy dla odśmiecacza. (Dzięki ecatmur za pierwsze wskazanie).
Dobrym sposobem rozwiązania tego problemu byłoby chirurgiczne przerwanie cyklu po opuszczeniu exceptklauzuli, co robi Python 3. Rozwiązanie w Pythonie 2 jest dużo brzydsze: masz do dyspozycji funkcję ad-hoc sys.exc_info(), która działa tylko wewnątrz except klauzuli . Zwraca krotkę zawierającą wyjątek, typ wyjątku i ślad zwrotny dla dowolnego wyjątku, który jest obecnie obsługiwany.
Więc jeśli jesteś wewnątrz exceptklauzuli, możesz użyć danych wyjściowych sys.exc_info()wraz z tracebackmodułem do zrobienia różnych przydatnych rzeczy:
>>> 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
Ale jak wskazuje twoja edycja, próbujesz uzyskać dane śledzenia, które zostałyby wydrukowane, gdyby twój wyjątek nie został obsłużony, po tym, jak został już obsłużony. To znacznie trudniejsze pytanie. Niestety sys.exc_infowraca, (None, None, None)gdy żaden wyjątek nie jest obsługiwany. Inne powiązane sysatrybuty też nie pomagają. sys.exc_tracebackjest przestarzały i niezdefiniowany, gdy żaden wyjątek nie jest obsługiwany; sys.last_tracebackwydaje się idealny, ale wydaje się, że jest definiowany tylko podczas sesji interaktywnych.
Jeśli możesz kontrolować sposób wywoływania wyjątku, możesz użyć inspecti niestandardowego wyjątku do przechowywania niektórych informacji. Ale nie jestem do końca pewien, jak to zadziała.
Prawdę mówiąc, wyłapywanie i zwracanie wyjątku jest czymś niezwykłym. Może to oznaczać, że i tak musisz dokonać refaktoryzacji.