2012-02-18 9 views
1

関数が定義されたフレームをプログラムで見つける方法はありますか?関数が定義されたフレームオブジェクトを取得する

def foo(): 
    def bar(): 
     pass 
    return bar 

bar = foo() 

get_defining_frame(foo) # should be the same as inspect.currentframe() 
get_defining_frame(bar) # should be the frame created by the call to foo 

ありがとう:私はこのように働くだろう機能get_defining_frameのようなものを探しています!

答えて

0

フレームはすべての関数呼び出しで作成/削除されます。だから、呼び出すとき:あなたのコード例では

get_defining_frame(bar) 

は、 barが作成されたフレームはすでになくなっています。

関数オブジェクトは、定義されたフレームへの参照を保持していません。他のすべてのローカル変数が解放されないようにするため、良いことです。

なぜこれが必要ですか?

+0

実行時にコードを視覚化しようとしています。しかし、フレームがまだアクセス可能であることはかなり確信しています...変数 'x'が' foo'にあれば、 'bar'を呼び出しても' x'にアクセスできるはずです。 – user1196203

+0

'x'にはそうですが、' x'とも呼ばれるフレームにはありません。ローカル変数がネストされた関数から参照されるとき、実際にはセル変数になります。通常のローカル変数と比較して、間接参照の余分なレイヤーがあります。正確には、フレームオブジェクトは固執する必要がありません。セル変数は生きていて(個別に)保持され、フレームオブジェクトに関するその他すべてが破棄されます。 –

0

自分で保管しない限り(おそらくデコレータ)、この種の情報を取得することはできません。 bar.__code__bar.__closure__をご覧ください。多分それらはあなたに十分な情報を提供します。 __closure__は、バーが作成されたときのコンテキスト全体を格納しません。メモリ効率の理由からbarが参照する変数のみを格納します。 、これは本当にめちゃくちゃにガベージコレクションを意志使用してスタック全体のフレームを格納すると(スタック内の任意の場所を参照するものは何もGC-EDになることはできませんを意味していることを念頭に置い

def save_frame(func): 
    frame=inspect.currentframe().f_back 
    func.__frame = frame 
    return func 

ベア:

トリックを行う必要がありますデコレータだから__closure__は参照されているものだけをキャプチャします)。

関連する問題