오류의 이름과 추적 정보를 변수에 저장하고 싶습니다. 여기 내 시도가 있습니다.
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 ()는 세 가지 값 (유형, 값, 역 추적)이있는 튜플을 반환합니다.
- 여기서 type은 처리되는 Exception의 예외 유형을 가져옵니다.
- value는 예외 클래스의 생성자에 전달되는 인수입니다.
- traceback에는 예외가 발생한 위치 등과 같은 스택 정보가 포함됩니다.
예를 들어, 다음 프로그램에서
try:
a = 1/0
except Exception,e:
exc_tuple = sys.exc_info()
이제 튜플을 인쇄하면 값은 다음과 같습니다.
- exc_tuple [0] 값은 ” ZeroDivisionError “가됩니다.
- exc_tuple [1] 값은 ” 정수 나누기 또는 0으로 모듈로 “입니다 (예외 클래스에 매개 변수로 전달 된 문자열).
- exc_tuple [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()
가 발생하고 수집에 실패하기 때문입니다. 이것은 역 추적 객체가 적시에 지워지지 않고 gc.collect()
in finally
섹션에 대한 명시적인 호출조차 아무것도 하지 않는 ipython / jupyter 노트북 환경에서 특정 문제인 것으로 보입니다 . 그리고 그로 인해 메모리를 회수하지 못하는 거대한 객체가 있다면 그것은 큰 문제입니다 (예를 들어,이 솔루션이없는 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)
jupyter 노트북의 경우 최소한 예외 핸들러 내에서이를 수행해야합니다.
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로 테스트되었습니다.
추신 ipython 또는 jupyter 노트북 환경의 문제 %tb
는 추적을 저장하고 나중에 언제든지 사용할 수 있도록 만드는 마법 이 있다는 것 입니다. 결과적으로 locals()
트레이스 백에 참여하는 모든 프레임은 노트북이 종료되거나 다른 예외가 이전에 저장된 백 트레이스를 덮어 쓸 때까지 해제되지 않습니다. 이것은 매우 문제가됩니다. 프레임을 청소하지 않고 트레이스 백을 저장해서는 안됩니다. 여기에 수정 사항이 제출 되었습니다 .
답변
이 개체는 Exception.with_traceback()
함수 에서 매개 변수로 사용할 수 있습니다 .
except Exception as e:
tb = sys.exc_info()
print(e.with_traceback(tb[2]))