2016-10-06 6 views
1

내가 다른 파일 my_file.py에서 내 파일 decorators.py파이썬 예외가 발생한 실제 행 번호를 얻는 방법은 무엇입니까?

def catch_exceptions(function):           #Line #1 
    @wraps(function)              #Line #2 
    def decorator(*args, **kwargs):          #Line #3 
     try:                #Line #4 
      return function(*args, **kwargs)        #Line #5 
     except Exception as e:           #Line #6 
      exc_type, exc_obj, exc_tb = sys.exc_info()     #Line #7 
      fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] #Line #8 
      print "E=%s, F=%s, L=%s" % (str(e), fname, exc_tb.tb_lineno) #Line #9 
    return decorator              #Line #10 

에서 다음 파이썬 장식을 가지고,이 같은 catch_exceptions 장식을 사용

from decorators import catch_exceptions         #Line #1 
@catch_exceptions               #Line #2 
def my_method()               #Line #3 
    print (10/0 - 5/0)             #Line #4 

내가 그것을 실행하면, 나는 다음과 같은 출력을 얻을 :

E=integer division or modulo by zero, F=decorators.py, L=5 

예외 위치 대신 decorators.py, line # 5, 예외가 원래 발생한 실제 파일과 행 번호를보고하려면 어떻게해야합니까? 그것은 my_file.py의 4 번 줄입니다.

답변

3

당신은 그것을 할 싶다면하지만 여전히 당신이 알아야 할 traceback입니다.

나는 인쇄하고 있던 filename도 실수 였다고 생각합니다.

따라서 exc_tb은 실제 traceback 개체입니다. 그리고 데이터는

복귀 역 추적 개체에서 추출한 TB "전처리"스택 트레이스 같이 한계까지의 목록을 수행 할 extract_tb() 의해 추출하는가요. 스택 추적의 다른 형식을 지정할 때 유용합니다. limit가 생략되거나 None 인 경우 모든 항목이 추출됩니다. "사전 처리 된"스택 추적 항목은 일반적으로 스택 추적을 위해 인쇄되는 정보를 나타내는 4- 튜플 (파일 이름, 줄 번호, 함수 이름 *, 텍스트)입니다.

따라서 traceback.extract_tb(exc_tb)의 두 번째 마지막 요소는 데코레이터에서 발생하는 예외이며 마지막 요소는 함수에 포함됩니다. 따라서 마지막 색인 (-1)이 우리가 필요로하는 것입니다. 그렇다면 traceback.extract_tb(exc_tb)[-1][0]은 (아마도) decorators.pytraceback.extract_tb(exc_tb)[-1][1]이 아닌 파일 이름이 될 것입니다 (예외가 발생했을 때).

+0

예. 이 작품! 참고로, traceback.extract_tb (exc_tb) 목록의 마지막 요소를 선택하는 것이 더 좋습니다. 이 데코레이터는 메소드와 연관된 데코레이터 스택에 나타날 수 있습니다. 나는 그에 따라 당신의 대답에 편집을 게시했다. –

+0

@SaqibAli yeap, 그게 더 낫 네 덕분에 편집을 승인했지만 _last_, _second_, _first_와 같은 단어도 처리해야하므로 다른 편집을 적용했다. 그것은 도움이 된 것을 기쁘게 생각합니다! –

3

당신은 traceback 모듈

import traceback 

try: 
    function_that_raises_exception() 
except Exception: 
    traceback.print_exc() 

그것은 전체 스택 추적을 인쇄합니다 들여다 할 수 있습니다. 당신이 다음

from functools import wraps 
import sys, os, traceback 

def catch_exceptions(function):           
    @wraps(function)              
    def decorator(*args, **kwargs):          
     try:                
      return function(*args, **kwargs)        
     except Exception as e:            
      exc_type, exc_obj, exc_tb = sys.exc_info() 
      print "E=%s, F=%s, L=%s" % (str(e), traceback.extract_tb(exc_tb)[-1][0], traceback.extract_tb(exc_tb)[-1][1])) 
    return decorator 

을 설명

관련 문제