2012-10-08 11 views
11

Python関数のコードオブジェクトは__code__です。コードオブジェクトのPython関数の取得

sys.settraceトレースframeは、f_codeコードオブジェクトを持っています。

トレーサを関数として呼び出す場合、関数オブジェクト(およびその__annotation__メンバ)を取得するにはどうすればよいですか?

これまでのところ、試行錯誤によって、私が持っている:

if hasattr(frame.f_globals.get(frame.f_code.co_name),"__annotations__"): 

これはではなく、クラスのメンバ関数のために、機能のために働くようです。悪いことに、クラスメンバ関数を同じ名前の最上位関数と混同します。

(。私は、Python 3.2.3(Xubuntuの)に私は、Python 3.3 inspectモジュールがsignature機能を持っていることを確認しています。これは、コードオブジェクトのための注釈を返しますか、それはあまりにも関数オブジェクトを必要としない?)

答えて

5

inspect.getframeinfoモジュールを介して。 私は、Pythonでこれを行う簡単な方法はない - ほとんどの場合、関数をまだ持たずにコードオブジェクトを取得できることは、フレームinstrospectionによるものです。

Inspectのgetframeinfo関数は、実行されているフレームに関する情報を返しますが、その名前を取得して関数オブジェクトを取得できます。

タフこれは実装に依存し、いくつかの欠点を持っている:依存

>>> import inspect 
>>> def a(): 
... return inspect.currentframe() 
... 

>>> inspect.getframeinfo(a()) 
Traceback(filename='<stdin>', lineno=2, function='a', code_context=None, index=None) 
>>> b = inspect.getframeinfo(a()) 
>>> b.function 
'a' 

もう一つの方法は、まだ実装は、コードオブジェクトとする参照元を取得するためにGCモジュール(ガベージコレクタ)を使用することです。

>>> import gc 
>>> from types import FunctionType 
>>> def a(): pass 
... 
>>> code = a.__code__ 

>>> [obj for obj in gc.get_referrers(code) if isinstance(obj, FunctionType) ][0] 
<function a at 0x7f1ef4484500> 
>>> 

からfunc_code

+0

'inspect.getframeinfo'タプルの' function'フィールドで__code__を置き換える必要はPython 2いずれかの文字列ではなく、関数オブジェクトのようです - これは、Python 3用です。そして、gcアプローチは複数のリファラーを危険にさらしますか? – Will

+0

gc.get_referrers(...)を使用して終了しました[0] – Will

+1

func_code/__ code__がリスト内包にしたいコードオブジェクトであるかどうかをチェックすることができます。同じコードオブジェクトと異なるクロージャデコレータで。私はf_localsとfunc_closureのcell_contentsをそれぞれ比較することができます。 –

関連する問題