2016-10-06 10 views
1

は、私は別のファイルmy_file.pyでは、私のファイルdecorators.pyPython例外が発生した場所の実際の行番号を取得する方法は?

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 

で、次のPythonのデコレータを持って、私はこのような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、行番号5、実際に例外が発生した場所の実際のファイルと行番号を報告するにはどうすればよいですか?それはmy_file.pyの4行目です。

答えて

3

あなたはその後、

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 

を説明した。しかし、それはまだあなたが知っている必要がありtracebackだとしてそれをしたい場合。

私は印刷していたfilenameも間違いだと思います。

したがってexc_tbは、実際のtracebackオブジェクトです。そして、データの抽出はextract_tb()によって行われます。

トレースバックオブジェクトtbから抽出された最大限の "前処理された"スタックトレースエントリのリストを返します。これは、スタックトレースの代替フォーマットに役立ちます。 limitを省略するかNoneにすると、すべてのエントリが抽出されます。 "pre-processed"スタックトレースエントリは、通常はスタックトレース用に印刷される情報を表す4タプル(ファイル名、行番号、関数名*、テキスト)です。

したがって、traceback.extract_tb(exc_tb)の2番目の最後の要素は、デコレータで発生した例外で、最後は関数内にあります。したがって、最後のインデックス(-1)が必要です。その後、traceback.extract_tb(exc_tb)[-1][0]は、あなたの希望するファイルのファイル名になります。decorators.pytraceback.extract_tb(exc_tb)[-1][1]は、例外が発生したときの行になりません。

+0

はい。これは動作します! FYIでは、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() 

に見てみたいことがあります。

関連する問題