예외 개체에서 추적 정보 추출
출처를 알 수없는 예외 객체가 주어지면 추적을 얻을 수있는 방법이 있습니까? 다음과 같은 코드가 있습니다.
def stuff():
try:
.....
return useful
except Exception as e:
return e
result = stuff()
if isinstance(result, Exception):
result.traceback <-- How?
Exception 객체가있는 경우 어떻게 트레이스 백을 추출 할 수 있습니까?
이 질문에 대한 답은 사용중인 Python 버전에 따라 다릅니다.
Python 3에서
간단합니다. 예외 __traceback__
에는 트레이스 백을 포함 하는 속성이 제공됩니다. 이 속성은 쓰기 가능하며 with_traceback
예외 방법을 사용하여 편리하게 설정할 수 있습니다 .
raise Exception("foo occurred").with_traceback(tracebackobj)
이러한 기능은 raise
문서의 일부로 최소한으로 설명됩니다 .
답변의이 부분에 대한 모든 크레딧 은이 정보 를 처음 게시 한 Vyctor에게 가야합니다 . 이 답변이 맨 위에 붙어 있고 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
및 사용자 지정 예외 를 사용하여 일부 정보를 저장할 수 있습니다. 그러나 나는 그것이 어떻게 작동하는지 완전히 확신하지 못합니다.
진실을 말하면 예외를 포착하고 반환하는 것은 특이한 일입니다. 어쨌든 리팩토링해야한다는 신호일 수 있습니다.
이후 파이썬 3.0 [3109 PEP] (가) 클래스에 내장은 Exception
가 __traceback__
포함 속성 traceback object
(파이썬 3.2.3로)를 :
>>> try:
... raise Exception()
... except Exception as e:
... tb = e.__traceback__
...
>>> tb
<traceback object at 0x00000000022A9208>
문제는 인터넷 검색__traceback__
후 잠시 동안 몇 개의 기사 만 찾았지만 .NET을 사용해야하는 이유 또는 이유를 설명하는 기사가 없다는 것 __traceback__
입니다.
그러나에 대한 Python 3 문서는 다음과raise
같이 말합니다.
A traceback object is normally created automatically when an exception is raised and attached to it as the
__traceback__
attribute, which is writable.
So I assume it's meant to be used.
A way to get traceback as a string from an exception object in Python 3:
import traceback
# `e` is an exception object that you get from somewhere
traceback_str = ''.join(traceback.format_tb(e.__traceback__))
traceback.format_tb(...)
returns a list of strings. ''.join(...)
joins them together. For more reference, please visit: https://docs.python.org/3/library/traceback.html#traceback.format_tb
As an aside, if you want to actually get the full traceback as you would see it printed to your terminal, you want this:
>>> try:
... print(1/0)
... except Exception as e:
... exc = e
...
>>> exc
ZeroDivisionError('division by zero')
>>> tb_str = traceback.format_exception(etype=type(exc), value=exc, tb=exc.__traceback__)
>>> tb_str
['Traceback (most recent call last):\n', ' File "<stdin>", line 2, in <module>\n', 'ZeroDivisionError: division by zero\n']
>>> print("".join(tb_str))
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ZeroDivisionError: division by zero
If you use format_tb
as above answers suggest you'll get less information:
>>> tb_str = "".join(traceback.format_tb(exc.__traceback__))
>>> print("".join(tb_str))
File "<stdin>", line 2, in <module>
There's a very good reason the traceback is not stored in the exception; because the traceback holds references to its stack's locals, this would result in a circular reference and (temporary) memory leak until the circular GC kicks in. (This is why you should never store the traceback in a local variable.)
About the only thing I can think of would be for you to monkeypatch stuff
's globals so that when it thinks it's catching Exception
it's actually catching a specialised type and the exception propagates to you as the caller:
module_containing_stuff.Exception = type("BogusException", (Exception,), {})
try:
stuff()
except Exception:
import sys
print sys.exc_info()
참고URL : https://stackoverflow.com/questions/11414894/extract-traceback-info-from-an-exception-object
'programing' 카테고리의 다른 글
Android Studio : 실행 또는 디버그 전에 APK를 자동으로 제거 (또는 adb 명령 실행)하는 방법은 무엇입니까? (0) | 2020.08.31 |
---|---|
파이썬의 대화식 REPL 모드와 같은 것이 있지만 Java 용입니까? (0) | 2020.08.31 |
i ++가 원 자성이 아닌 이유는 무엇입니까? (0) | 2020.08.30 |
Android : 프로그래밍 방식으로 화면을 켜고 끄는 방법은 무엇입니까? (0) | 2020.08.30 |
AngularJS (0) | 2020.08.30 |