예외를 발생시킨 예외 설명 및 스택 추적을 모두 문자열로 가져옵니다.
Python에서 스택 트레이스와 예외에 대한 많은 게시물을 보았습니다.하지만 내가 필요한 걸 찾지 못했어.
Python 2.7 코드 덩어리가 있어 예외가 발생할 수 있습니다.오류를 일으킨 스택트레이스(콘솔에 표시하기 위해 사용하는 모든 것)와 완전한 설명을 문자열에 할당하고 싶습니다.이 문자열은 GUI 텍스트 상자에 인쇄하기 위해 필요합니다.
다음과 같은 경우:
try:
    method_that_can_raise_an_exception(params)
except Exception as e:
    print_to_textbox(complete_exception_description(e))
 
문제는 기능이란 무엇인가?
를 참조해 주세요.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!
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__attribute)를 사용하면 다른 함수에 대한 인수로서 보다 쉽게 전달할 수 있습니다.
Python 3.5+의 경우:
따라서 스택 트레이스는 다른 예외와 마찬가지로 예외에서 얻을 수 있습니다.사용(교환만 하면 됨)ex(예외는):
print("".join(traceback.TracebackException.from_exception(ex).format())
 
이를 위한 확장 예 및 기타 기능:
import traceback
try:
    1/0
except Exception as ex:
    print("".join(traceback.TracebackException.from_exception(ex).format()) == traceback.format_exc() == "".join(traceback.format_exception(type(ex), ex, ex.__traceback__))) # This is True !!
    print("".join(traceback.TracebackException.from_exception(ex).format()))
 
출력은 다음과 같습니다.
True
Traceback (most recent call last):
  File "untidsfsdfsdftled.py", line 29, in <module>
    1/0
ZeroDivisionError: division by zero
>>> 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 사용하시는 분
사용.traceback모듈 및exception.__traceback__다음과 같이 스택을 추출할 수 있습니다.
- 를 사용하여 현재 스택슬롯을 취득하다
traceback.extract_stack() - 마지막 3개의 요소를 삭제합니다(디버깅 기능을 시작한 스택 내의 엔트리입니다).
 -  
__traceback__에서 from from음음을 사용하여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
또한 내장 Python 모듈 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을 사용하고 있습니다.
예외 메시지와 스택 트레이스 메시지를 python이 에러를 발생시켰을 때와 똑같이 만드는 것이 목표인 경우, 다음은 python 2+3 모두에서 작동합니다.
import sys, traceback
def format_stacktrace():
    parts = ["Traceback (most recent call last):\n"]
    parts.extend(traceback.format_stack(limit=25)[:-2])
    parts.extend(traceback.format_exception(*sys.exc_info())[1:])
    return "".join(parts)
# EXAMPLE BELOW...
def a():
    b()
def b():
    c()
def c():
    d()
def d():
    assert False, "Noooh don't do it."
print("THIS IS THE FORMATTED STRING")
print("============================\n")
try:
    a()
except:
    stacktrace = format_stacktrace()
    print(stacktrace)
print("THIS IS HOW PYTHON DOES IT")
print("==========================\n")
a()
 
.format_stacktrace()스택에서 콜하고 나머지 콜에 참여합니다.실행 시 위의 예에서는 다음 출력이 나타납니다.
THIS IS THE FORMATTED STRING
============================
Traceback (most recent call last):
  File "test.py", line 31, in <module>
    a()
  File "test.py", line 12, in a
    b()
  File "test.py", line 16, in b
    c()
  File "test.py", line 20, in c
    d()
  File "test.py", line 24, in d
    assert False, "Noooh don't do it."
AssertionError: Noooh don't do it.
THIS IS HOW PYTHON DOES IT
==========================
Traceback (most recent call last):
  File "test.py", line 38, in <module>
    a()
  File "test.py", line 12, in a
    b()
  File "test.py", line 16, in b
    c()
  File "test.py", line 20, in c
    d()
  File "test.py", line 24, in d
    assert False, "Noooh don't do it."
AssertionError: Noooh don't do it.
내 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));
 
(배경:그래서 너무 당황스러웠어요.Promise와 함께하다Exception도 한 하기 때문에 을 취득하기가 .
트레이스백을 dict 목록으로 변환하는 경우(python > 3.5의 경우):
from traceback import TracebackException
def list_traceback(exc_value: BaseException):
    result = list()
    # get previous fails, so errors are appended by order of execution
    if exc_value.__context__:
        result += list_traceback(exc_value.__context__)
    # convert Exception into TracebackException
    tbe = TracebackException.from_exception(exc_value)
    # get stacktrace (cascade methods calls)
    error_lines = list()
    for frame_summary in tbe.stack:
        summary_details = {
            'filename': frame_summary.filename,
            'method'  : frame_summary.name,
            'lineno'  : frame_summary.lineno,
            'code'    : frame_summary.line
        }
        error_lines.append(summary_details)
    # append error, by order of execution
    result.append({"error_lines": error_lines,
                   "type"       : tbe.exc_type.__name__,
                   "message"    : str(tbe)})
    return result
 
그 결과(예시)
[
   {
      "error_lines": [
         {
            "filename": "/home/demo/file2.py",
            "method": "do_error_2",
            "lineno": 18,
            "code": "a=1/0"
         }
      ],
      "type": "ZeroDivisionError",
      "message": "division by zero"
   },
   {
      "error_lines": [
         {
            "filename": "/home/demo/file_main.py",
            "method": "demo2",
            "lineno": 50,
            "code": "file2.DEMO().do_error_2()"
         },
         {
            "filename": "/home/demo/file2.py",
            "method": "do_error_2",
            "lineno": 20,
            "code": "raise AssertionError(\"Raised inside the except, after division by zero\")"
         }
      ],
      "type": "AssertionError",
      "message": "Raised inside the except, after division by zero"
   }
]
언급URL : https://stackoverflow.com/questions/4564559/get-exception-description-and-stack-trace-which-caused-an-exception-all-as-a-st
'source' 카테고리의 다른 글
| 블레이드 템플릿의 모든 HTML 이스케이프 Larabel (0) | 2022.11.05 | 
|---|---|
| Mockito는 여러 번 호출된 메서드의 인수를 캡처할 수 있습니까? (0) | 2022.11.05 | 
| QUERY 패킷을 보내는 중 오류 발생 (0) | 2022.11.05 | 
| 레지스트리 키 '...'의 값은 '1.7'이지만 '1.6'은 필수입니다.Java 1.7이 설치되어 레지스트리가 이를 가리키고 있다. (0) | 2022.11.05 | 
| 일주일보다 새로운 행을 선택하려면 어떻게 해야 합니까? (0) | 2022.11.05 |