2010-03-01 3 views
17

파이썬에서 예외가 발생하면 스택을 검사 할 수 있습니까? 깊이를 판단 할 수 있습니까? traceback 모듈을 살펴 보았지만이를 사용하는 방법을 알 수 없습니다.어떻게 파이썬에서 예외의 스택 추적을 프로그래밍 방식으로 검사 할 수 있습니까?

내 목표는 호출했을 수있는 모든 기능에 의해 발생하는 예외를 포착하지 않고도 eval 표현식을 파싱하는 동안 발생하는 예외를 잡는 것입니다. 평가판 사용에 대해 나를 괴롭히지 마십시오. 그건 내 결정이 아니야.

참고 : 대화식으로 프로그래밍 방식으로이 작업을 수행하려고합니다.

답변

13

traceback으로 충분합니다. 설명서에 잘 설명되어 있다고 가정합니다. 간단한 예는 :

import sys 
import traceback 

try: 
    eval('a') 
except NameError: 
    traceback.print_exc(file=sys.stdout) 
+2

추적 표시를 인쇄하려고하지 않습니다. 나는 그것을 조사하려고 노력하고있다. 이것이 평가 결과 텍스트 나 평가 된 텍스트에 의해 호출 된 함수에서 예외가 발생했는지 어떻게 알 수 있습니까? –

+0

'eval' 텍스트가 잘못되면 SyntaxError가 발생합니다. –

+0

평가 텍스트가 잘못되면 많은 종류의 오류가 발생할 수 있습니다.나는 검사를 사용하여 추적 결과의 깊이를보고 원래의 텍스트를 평가하여 오류가 발생했는지 또는 호출 된 함수의 본문에 있는지 여부를 확인했습니다. –

0

inspect에 대한 AndiDog의 답변뿐만 아니라, pdb 당신이 지역 주민과 같은 것들을 검사, 최대 이동 스택 아래로 할 수 있습니다. 표준 라이브러리 pdb.py에있는 출처는 그러한 일을하는 법을 배우는 데 도움이 될 수 있습니다.

4

나는 역 추적 모듈을 좋아한다.

sys.exc_info()을 사용하여 추적 개체를 얻을 수 있습니다. 그런 다음 해당 객체를 사용하여 traceback.extract_tb()을 사용하여 목록 전처리 된 역 추적 항목 목록을 가져올 수 있습니다. 당신은 함수를 정의 http://docs.python.org/library/traceback.html

1

() : http://docs.python.org/library/sys.html

및 역 추적 모듈 :

import sys 
import traceback, inspect 

try: 
    f = open("nonExistant file",'r') 
except: 
    (exc_type, exc_value, exc_traceback) = sys.exc_info() 
    #print exception type 
    print exc_type 
    tb_list = traceback.extract_tb(sys.exc_info()[2]) 
    tb_list = traceback.format_list(tb_list) 
    for elt in tb_list: 
     print elt 
     #Do any processing you need here. 

은 sys 모듈을 참조하십시오 다음과 같이 그럼 당신은 traceback.format_list()를 사용하여 읽을 수있는 목록을 얻을 수 있습니다

def raiseErr(): 
    for f in inspect.stack(): print '-', inspect.getframeinfo(f[0]) 

귀하의 모듈에서 전화하십시오 :

raiseErr() 

기능 raiseErr은 사용자가 호출 한 장소에 대한 정보를 인쇄합니다. 더 정교한

, 당신은 그렇게 할 수 있습니다 :

def tr(): 
    print '* - '*10, 
    print sys._getframe(1).f_code.co_name 

그리고 당신은 추적을 원하는 장소에 전화 :

import inspect, traceback 
A = [inspect.getframeinfo(f[0]) for f in inspect.stack()] 
print "traceback structure fields:", filter(lambda s: s[0] != '_', dir(A[0])) 
print A[0].filename, A[0].lineno 
for f in inspect.stack(): 
    F = inspect.getframeinfo(f[0]) 
    print '-', F.filename, F.lineno, '\t', F.code_context[0].strip() 

다른 가능성은이 함수를 정의하는 것입니다. 모든 추적을 원하면 _getframe(1)에서 1부터 반복기를 작성하십시오.

관련 문제