2012-07-19 7 views
7

私は階層構造を持っているとしますが、にアクセスできるようにしたいと考えています(変更はありません)親のスコープです。ここでは例を示します。親のスコープをPythonで読む

def f(): 
    a = 2 
    b = 1 
    def g(): 
     b = 2 
     c = 1 
     print globals() #contains a=1 and d=4 
     print locals() #contains b=2 and c=1, but no a 
     print dict(globals(), **locals()) #contains a=1, d=4 (from the globals), b=2 and c=1 (from g) 
     # I want a=2 and b=1 (from f), d=4 (from globals) and no c 
    g() 
a = 1 
d = 4 
f() 

私はg内からfのスコープにアクセスすることはできますか?

+0

ここにサンプルコードがあります。あなたはそれを試すことができます。 –

+0

これはあなたにとって興味深いと思います:http://ynniv.com/blog/2007/08/closures-in-python.html – fuaaark

+0

@arxanas私が持っているサンプルコードはそれをしませんが、問題を調べるには、10行目を参照してください。 –

答えて

5

一般に、Pythonでは使用できません。あなたのPython実装がスタックフレームをサポートしている場合(CPythonは)、inspectモジュールを使用して呼び出し関数のフレームを検査し、ローカル変数を抽出することができますが、これは解決したい問題。もしあなたがこれを必要と思うならば、あなたのデザインにはある程度の欠陥があります。

inspectを使用すると、コールスタックに入ることができ、レキシカルスコープのスタックでは使用できません。 gf()から返すと、fのスコープはなくなるため、存在しないためにアクセスする方法はありません。

+0

これを行うことができないのはセキュリティの理由ですか?スコープが微妙で混乱しているのが分かりますが、fの中から 'g'を呼び出すと' f'のスコープが存在することになります。後で 'f'(!)の実行に戻るとき 理由Iこれは[副作用のユニットテスト]のためだと考えていた(http://stackoverflow.com/questions/11559401/testing-for-side-effects-in-python#comment15290923_11559401)...:s –

+5

@hayden:いいえ、セキュリティ上の理由ではありません。私が言ったように、あなたのPythonの実装がスタックフレームをサポートしているなら、コールスタックの上に行くことができます - 'inspect.currentframe()。f_back.f_locals'のようなものを呼び出して呼び出しフレームのローカルを取得します。あなたの例では 'f'の*レキシカル*スコープから変数にアクセスできない理由は、この概念が意味を持たないからです。呼び出しスタックには 'f'のインスタンスが複数存在することがあります。すべてが異なる地方であるか、まったく存在しない可能性があります。 –

+1

あなたが*このようなことをするべきではない理由は、動的スコープ(つまり、実質的に任意のプログラミング言語)に依存するように、語彙スコープを持つプログラミング言語の要点に反します。詳細については、http://en.wikipedia.org/wiki/Dynamic_scoping#Lexical_scoping_and_dynamic_scopingを参照してください。 –

関連する問題