예외를 일으킨 예외 설명 및 스택 추적을 모두 문자열로 가져옵니다.
파이썬에서 스택 추적 및 예외에 대한 많은 게시물을 보았습니다. 그러나 내가 필요한 것을 찾지 못했습니다.
예외가 발생할 수있는 Python 2.7 코드 덩어리가 있습니다. 나는 그것을 잡아서 문자열 에 전체 설명과 오류를 일으킨 스택 추적을 할당하고 싶습니다 (단지 콘솔에서 볼 때 사용하는 모든 것). GUI의 텍스트 상자에 인쇄하려면이 문자열이 필요합니다.
이 같은:
try:
method_that_can_raise_an_exception(params)
except Exception as e:
print_to_textbox(complete_exception_description(e))
문제는 : 기능 complete_exception_description
이란 무엇 인가?
traceback
모듈, 특히 format_exc()
기능을 참조하십시오 . 이곳까지 .
import traceback
try:
raise ValueError
except ValueError:
tb = traceback.format_exc()
else:
tb = "No error"
finally:
print tb
전체 스택 추적을 얻는 방법을 보여주기 위해 상당히 복잡한 스택 추적을 만들어 봅시다.
def raise_error():
raise RuntimeError('something bad happened!')
def do_something_that_might_error():
raise_error()
전체 스택 추적 로깅
모범 사례는 모듈에 로거를 설정하는 것입니다. 모듈의 이름을 알고 레벨을 변경할 수 있습니다 (핸들러와 같은 다른 속성 중에서)
import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
이 로거를 사용하여 오류를 얻을 수 있습니다.
try:
do_something_that_might_error()
except Exception as error:
logger.exception(error)
어떤 로그 :
ERROR:__main__:something bad happened!
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "<stdin>", line 2, in do_something_that_might_error
File "<stdin>", line 2, in raise_error
RuntimeError: something bad happened!
따라서 오류가 발생했을 때와 동일한 결과를 얻습니다.
>>> do_something_that_might_error()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in do_something_that_might_error
File "<stdin>", line 2, in raise_error
RuntimeError: something bad happened!
문자열 만 얻기
실제로 문자열을 원한다면 traceback.format_exc
대신 함수를 사용 하여 문자열 로깅을 보여줍니다.
import traceback
try:
do_something_that_might_error()
except Exception as error:
just_the_string = traceback.format_exc()
logger.debug(just_the_string)
어떤 로그 :
DEBUG:__main__:Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "<stdin>", line 2, in do_something_that_might_error
File "<stdin>", line 2, in raise_error
RuntimeError: something bad happened!
>>> import sys
>>> import traceback
>>> try:
... 5 / 0
... except ZeroDivisionError as e:
... type_, value_, traceback_ = sys.exc_info()
>>> traceback.format_tb(traceback_)
[' File "<stdin>", line 2, in <module>\n']
>>> value_
ZeroDivisionError('integer division or modulo by zero',)
>>> type_
<type 'exceptions.ZeroDivisionError'>
>>>
>>> 5 / 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero
sys.exc_info () 를 사용 하여 traceback
모듈 에서 정보와 함수를 수집하여 정보 를 형식화합니다. 형식을 지정하는 몇 가지 예는 다음과 같습니다 .
전체 예외 문자열은 다음과 같습니다.
>>> ex = traceback.format_exception(type_, value_, traceback_)
>>> ex
['Traceback (most recent call last):\n', ' File "<stdin>", line 2, in <module>\n', 'ZeroDivisionError: integer division or modulo by zero\n']
Python 3을 사용하면 다음 코드는 다음을 Exception
사용하여 얻을 수있는 것과 정확히 일치 하는 객체 를 포맷합니다 traceback.format_exc()
.
import traceback
try:
method_that_can_raise_an_exception(params)
except Exception as ex:
print(''.join(traceback.format_exception(etype=type(ex), value=ex, tb=ex.__traceback__)))
장점은 Exception
객체 만 필요하고 (기록 된 __traceback__
속성 덕분에 ) 추가 처리를 위해 다른 함수에 대한 인수로 더 쉽게 전달 될 수 있다는 것입니다.
Python-3을 사용하는 사람들
traceback
모듈을 사용하면 exception.__traceback__
다음과 같이 스택 추적을 추출 할 수 있습니다.
- 그랩 현재 사용하는 스택 추적을
traceback.extract_stack()
- 마지막 세 요소를 제거하십시오 (스택의 디버그 항목으로 이동 한 항목이므로)
- 를
__traceback__
사용하여 예외 객체에서 추가traceback.extract_tb()
- 사용하여 모든 것을 포맷
traceback.format_list()
import traceback
def exception_to_string(excp):
stack = traceback.extract_stack()[:-3] + traceback.extract_tb(excp.__traceback__) # add limit=??
pretty = traceback.format_list(stack)
return ''.join(pretty) + '\n {} {}'.format(excp.__class__,excp)
간단한 데모 :
def foo():
try:
something_invalid()
except Exception as e:
print(exception_to_string(e))
def bar():
return foo()
호출하면 다음과 같은 결과가 나타납니다 bar()
.
File "./test.py", line 57, in <module>
bar()
File "./test.py", line 55, in bar
return foo()
File "./test.py", line 50, in foo
something_invalid()
<class 'NameError'> name 'something_invalid' is not defined
내장 파이썬 모듈 cgitb 를 사용하여 로컬 변수 값, 소스 코드 컨텍스트, 함수 매개 변수 등을 포함하여 실제로 훌륭하고 형식이 지정된 예외 정보를 얻을 수 있습니다.
예를 들어이 코드의 경우 ...
import cgitb
cgitb.enable(format='text')
def func2(a, divisor):
return a / divisor
def func1(a, b):
c = b - 5
return func2(a, c)
func1(1, 5)
이 예외 출력을 얻습니다 ...
ZeroDivisionError
Python 3.4.2: C:\tools\python\python.exe
Tue Sep 22 15:29:33 2015
A problem occurred in a Python script. Here is the sequence of
function calls leading up to the error, in the order they occurred.
c:\TEMP\cgittest2.py in <module>()
7 def func1(a, b):
8 c = b - 5
9 return func2(a, c)
10
11 func1(1, 5)
func1 = <function func1>
c:\TEMP\cgittest2.py in func1(a=1, b=5)
7 def func1(a, b):
8 c = b - 5
9 return func2(a, c)
10
11 func1(1, 5)
global func2 = <function func2>
a = 1
c = 0
c:\TEMP\cgittest2.py in func2(a=1, divisor=0)
3
4 def func2(a, divisor):
5 return a / divisor
6
7 def func1(a, b):
a = 1
divisor = 0
ZeroDivisionError: division by zero
__cause__ = None
__class__ = <class 'ZeroDivisionError'>
__context__ = None
__delattr__ = <method-wrapper '__delattr__' of ZeroDivisionError object>
__dict__ = {}
__dir__ = <built-in method __dir__ of ZeroDivisionError object>
__doc__ = 'Second argument to a division or modulo operation was zero.'
__eq__ = <method-wrapper '__eq__' of ZeroDivisionError object>
__format__ = <built-in method __format__ of ZeroDivisionError object>
__ge__ = <method-wrapper '__ge__' of ZeroDivisionError object>
__getattribute__ = <method-wrapper '__getattribute__' of ZeroDivisionError object>
__gt__ = <method-wrapper '__gt__' of ZeroDivisionError object>
__hash__ = <method-wrapper '__hash__' of ZeroDivisionError object>
__init__ = <method-wrapper '__init__' of ZeroDivisionError object>
__le__ = <method-wrapper '__le__' of ZeroDivisionError object>
__lt__ = <method-wrapper '__lt__' of ZeroDivisionError object>
__ne__ = <method-wrapper '__ne__' of ZeroDivisionError object>
__new__ = <built-in method __new__ of type object>
__reduce__ = <built-in method __reduce__ of ZeroDivisionError object>
__reduce_ex__ = <built-in method __reduce_ex__ of ZeroDivisionError object>
__repr__ = <method-wrapper '__repr__' of ZeroDivisionError object>
__setattr__ = <method-wrapper '__setattr__' of ZeroDivisionError object>
__setstate__ = <built-in method __setstate__ of ZeroDivisionError object>
__sizeof__ = <built-in method __sizeof__ of ZeroDivisionError object>
__str__ = <method-wrapper '__str__' of ZeroDivisionError object>
__subclasshook__ = <built-in method __subclasshook__ of type object>
__suppress_context__ = False
__traceback__ = <traceback object>
args = ('division by zero',)
with_traceback = <built-in method with_traceback of ZeroDivisionError object>
The above is a description of an error in a Python program. Here is
the original traceback:
Traceback (most recent call last):
File "cgittest2.py", line 11, in <module>
func1(1, 5)
File "cgittest2.py", line 9, in func1
return func2(a, c)
File "cgittest2.py", line 5, in func2
return a / divisor
ZeroDivisionError: division by zero
예외가 처리되지 않을 때 동일한 정보를 얻으려면 다음과 같이 할 수 있습니다. 수행 import traceback
다음과 :
try:
...
except Exception as e:
print(traceback.print_tb(e.__traceback__))
Python 3.7을 사용하고 있습니다.
내 2 센트 :
import sys, traceback
try:
...
except Exception, e:
T, V, TB = sys.exc_info()
print ''.join(traceback.format_exception(T,V,TB))
다음 도우미 클래스를 정의했습니다.
import traceback
class TracedExeptions(object):
def __init__(self):
pass
def __enter__(self):
pass
def __exit__(self, etype, value, tb):
if value :
if not hasattr(value, 'traceString'):
value.traceString = "\n".join(traceback.format_exception(etype, value, tb))
return False
return True
나중에 다음과 같이 사용할 수 있습니다.
with TracedExeptions():
#some-code-which-might-throw-any-exception
나중에 다음과 같이 사용할 수 있습니다.
def log_err(ex):
if hasattr(ex, 'traceString'):
print("ERROR:{}".format(ex.traceString));
else:
print("ERROR:{}".format(ex));
(배경 : 나는 때문에 사용하는 frustraded 된 Promise
과의 함께 Exception
불행하게도 다른 장소에서 on_rejected 핸들러에 한 곳에서 발행되는 예외를 전달 S, 따라서이 원래 위치에서 역 추적을 얻을 어렵다)
'Programing' 카테고리의 다른 글
줄 끝에 줄 번호와 적중 횟수를 표시하도록 grep 출력을 어떻게 형식화 할 수 있습니까? (0) | 2020.02.29 |
---|---|
CMake 출력을 지우는 'cmake clean'명령 찾기 (0) | 2020.02.29 |
내용으로 div의 높이를 확장하십시오. (0) | 2020.02.29 |
'모듈 가져 오기'또는 '모듈 가져 오기에서'를 사용 하시겠습니까? (0) | 2020.02.29 |
R에 어떤 패키지 버전이로드되어 있는지 확인하는 방법 (0) | 2020.02.29 |