programing

traceback / sys.exc_info() 값을 변수에 저장하는 방법은 무엇입니까?

lovejava 2023. 6. 23. 21:08

traceback / sys.exc_info() 값을 변수에 저장하는 방법은 무엇입니까?

오류 이름과 추적 정보를 변수에 저장하고 싶습니다.제 시도는 이렇습니다.

import sys
try:
    try:
        print x
    except Exception, ex:
        raise NameError
except Exception, er:
    print "0", sys.exc_info()[0]
    print "1", sys.exc_info()[1]
    print "2", sys.exc_info()[2]

출력:

0 <type 'exceptions.NameError'>
1 
2 <traceback object at 0xbd5fc8>

원하는 출력:

0 NameError
1
2 Traceback (most recent call last):
  File "exception.py", line 6, in <module>
    raise NameError

추신: 트레이스백 모듈을 사용하여 쉽게 수행할 수 있다는 것을 알고 있지만, 여기에서 sys.exc_info()[2] 개체의 사용법을 알고 싶습니다.

이렇게 해야 합니다.

>>> import traceback
>>> try:
...   int('k')
... except:
...   var = traceback.format_exc()
... 
>>> print(var)
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ValueError: invalid literal for int() with base 10: 'k'

그러나 나중에 변수를 처리하는 방법에 따라 더 적합한 방법이 있을 수 있으므로 추적 문서를 살펴봐야 합니다.

sys.exc_info()는 세 개의 값(유형, 값, 트레이스백)이 있는 튜플을 반환합니다.

  1. 여기 유형은 처리 중인 예외의 예외 유형을 가져옵니다.
  2. value는 예외 클래스의 생성자에게 전달되는 인수입니다.
  3. 트레이스백에는 예외가 발생한 위치 등과 같은 스택 정보가 포함되어 있습니다.

예를 들어, 다음 프로그램에서

try:

    a = 1/0

except Exception,e:

    exc_tuple = sys.exc_info()

이제 튜플을 인쇄하면 값은 다음과 같습니다.

  1. exc_tuple[0] 값은 "ZeroDivisionError"가 됩니다.
  2. exc_tuple[1] 값은 "0으로 정수 나눗셈 또는 모듈로"가 됩니다(예외 클래스에 매개 변수로 전달되는 문자열).
  3. exc_memoryle[2] 값은 "(일부 메모리 주소에서) 트랙백 개체"가 됩니다.

예외를 문자열 형식으로 인쇄하여 위의 세부 정보를 가져올 수도 있습니다.

print str(e)

사용하다traceback.extract_stack()모듈 및 기능 이름과 라인 번호에 대한 편리한 액세스를 원하는 경우.

사용하다''.join(traceback.format_stack())만약 당신이 단지 그것처럼 보이는 끈을 원한다면.traceback.print_stack()산출량.

이 경우에도''.join()당신은 다중 줄 문자열을 얻을 것이다, 왜냐하면 요소들이.format_stack()들어있다\n아래 출력을 참조하십시오.

기억하세요import traceback.

다음은 에서 나온 결과입니다.traceback.extract_stack()가독성을 위해 서식이 추가되었습니다.

>>> traceback.extract_stack()
[
   ('<string>', 1, '<module>', None),
   ('C:\\Python\\lib\\idlelib\\run.py', 126, 'main', 'ret = method(*args, **kwargs)'),
   ('C:\\Python\\lib\\idlelib\\run.py', 353, 'runcode', 'exec(code, self.locals)'),
   ('<pyshell#1>', 1, '<module>', None)
]

다음은 에서 나온 결과입니다.''.join(traceback.format_stack())가독성을 위해 서식이 추가되었습니다.

>>> ''.join(traceback.format_stack())
'  File "<string>", line 1, in <module>\n
   File "C:\\Python\\lib\\idlelib\\run.py", line 126, in main\n
       ret = method(*args, **kwargs)\n
   File "C:\\Python\\lib\\idlelib\\run.py", line 353, in runcode\n
       exec(code, self.locals)\n  File "<pyshell#2>", line 1, in <module>\n'

예외 처리기에서 예외 개체 또는 추적 개체를 제거할 때는 순환 참조가 발생하고gc.collect()수집에 실패합니다.이는 ipython/jupyter 노트북 환경에서 트레이스백 개체가 적시에 지워지지 않고 명시적으로 호출되지 않는 특별한 문제인 것으로 보입니다.gc.collect()finally섹션은 아무것도 하지 않습니다.이로 인해 메모리를 회수하지 못하는 큰 개체가 있는 경우(예: CUDA의 메모리 부족 예외로 이 솔루션을 복구하려면 커널을 완전히 다시 시작해야 합니다),

일반적으로 추적 개체를 저장하려면 다음에 대한 참조를 삭제해야 합니다.locals() 예:

import sys, traceback, gc
type, val, tb = None, None, None
try:
    myfunc()
except:
    type, val, tb = sys.exc_info()
    traceback.clear_frames(tb)
# some cleanup code
gc.collect()
# and then use the tb:
if tb:
    raise type(val).with_traceback(tb)

주피터 노트북의 경우 최소한 예외 처리기 내부에서 이 작업을 수행해야 합니다.

try:
    myfunc()
except:
    type, val, tb = sys.exc_info()
    traceback.clear_frames(tb)
    raise type(val).with_traceback(tb)
finally:
    # cleanup code in here
    gc.collect()

python 3.7로 테스트되었습니다.

p.s. ipython 또는 jupyter 노트북 환경의 문제는 그것이 가지고 있다는 것입니다.%tb추적을 저장하고 나중에 언제든지 사용할 수 있도록 하는 마법.으로 임의의 결적으어것이든떤로과▁and.locals()추적에 참여하는 모든 프레임에서 노트북이 종료되거나 다른 예외가 이전에 저장된 역추적을 덮어쓸 때까지 해제되지 않습니다.이것은 매우 문제가 있습니다.프레임을 청소하지 않고 트레이스백을 저장해서는 안 됩니다.수정사항을 여기에 제출합니다.

개체는 를체다음매사수있다습니용할수에 있는 변수로 될 수 .Exception.with_traceback()함수:

except Exception as e:
    tb = sys.exc_info()
    print(e.with_traceback(tb[2]))

언급URL : https://stackoverflow.com/questions/8238360/how-to-save-traceback-sys-exc-info-values-in-a-variable