2011-12-01 10 views
5

ソースコード内のPython関数の行番号を取得したいと思います。私は、実行時に持っている何 は、また、結果に行番号を与えるpythonモジュールで関数の行番号を取得するにはどうすればいいですか?

inspect.getsourcelines(object)  

を検査モジュールは、クラスは、メソッドが

が見ていたオブジェクトです。

デコレータ付きのメソッドの場合は、行番号を参照してください。実際のデコレータのソースコードは、目的の関数のソースコードではなく、上のinspect関数のポイントから返されます。 これを回避する方法はありますか? (私はインタプリタが実行時にデコレータ内で関数を折り返すようなことを理解していますが、間違っている可能性があります)

答えて

4

一般的には簡単な解決法はありません。

デコレータは、与えられた関数が、通常、デコレータが設計された操作を実行するクロージャで「ラッピング」することによって、関数を返す関数です。

しかし、ファイルと行番号の情報は関数オブジェクト自体ではなく、ラップされた関数からラッパーにこの情報をコピーすることでそれらを "修正"することはできません。そのデータは代わりに関数のcodeオブジェクト(.func_codeで利用可能)に格納され、作成するすべてのクロージャ間で共有されます。

>>> def bar(x): 
...  def foo(): 
...   return x 
...  return foo 
... 
>>> f1 = bar(1) 
>>> f2 = bar(2) 
>>> f1() 
1 
>>> f2() 
2 
>>> f1.func_code is f2.func_code 
True 
>>> 
+0

私はexplnのおかげで、参照してください。 'func_code'であっても、行番号を取得しています。デコレータのソースコード。私は設定行番号を無視して進みます。デコレータを持つメソッドの場合私の質問は、メソッドが_any_デコレータを持っているかどうかを調べる方法です(デコレータ名は以前は知られていません) – Hari

+0

@Hari:デコレータは何でも望むものを返すことができます(クロージャでも、それが返される前に他の計算をしている可能性があります)、関数オブジェクトが装飾されているかどうかを知るための100%確実なメソッドはありません。 – 6502

1

wraptモジュールを使用すると、関数のソースを見つけるだけでなく、他のイントロスペクションを実行するために必要なメタデータを保存するデコレータを書くようにすることによってこの問題を解決します。それは改善されたfunctools.wrapsのようです。

関連する問題