2013-02-25 3 views
6

TL; DR:包含するスコープで見えるlocals()が必要です。スコープを格納するためのPython locals()

こんにちは、すべて。

私はいくつかの化学者の友人にPythonプログラミングのコースを教えています。私は本当に範囲を理解していますか?

は考えてみましょう:

def a(): 
    x = 1 
    def b(): 
     print(locals()) 
     print(globals()) 
    b() 

地元の人々は空の環境を印刷し、グローバルは、通常のグローバルを出力します。 xが格納されている環境にアクセスするにはどうすればよいですか?私がそれを参照することができるので、通訳者はそれを知っていることは明らかです。

関連:スコープはいつ発生しますか?あなたは、x = 3をコメントアウトした場合、コードが動作する

def a(): 
    x = 1 
    def b(): 
     a = x+2 
     x = 3 
    b() 

:= X + 2のみのx = 3が含まれている場合に、次のnameErrors。これは、Pythonがそれを解釈する前にコードに対して字句スコープを渡すことを意味しますか?

+0

リストが必要ですか?印刷用のグローバルの後にprint xを行うことができるからです。編集:xにprint xでアクセスし、x:1で満たされているlocals()であると言うことを忘れないでください。 –

+0

[Pythonで名前空間を呼び出すことからローカルを取得]の可能性があります(http://stackoverflow.com/questions/6618795/get-locals-from-calling-namespace-in-python) – piokuc

答えて

0

ステートメントprint(locals())は、最も近い囲みスコープ、つまりdef b():の機能を示します。 b()を呼び出すと、このb関数にローカルを出力し、xの定義はスコープの外になります。

def a(): 
    x = 1 
    def b(): 
     print(locals()) 
     print(globals()) 
    b() 
    print(locals()) 

xをローカル変数として出力します。あなたの2番目の質問については

def a(): 
    x = 1 
    def b(): 
     #a = x+2 
     x = 3 
    b() 

>>> a() 

には、エラーを与えません。

def a(): 
    x = 1 
    def b(): 
     a = x+2 
     #x = 3 
    b() 

>>> a() 

はエラーを生じない。

そして

def a(): 
    x = 1 
    def b(): 
     a = x+2 
     x = 3 
    b() 

>>> a() 

は、次のエラーを与える:UnboundLocalError: local variable 'x' referenced before assignment

IMO(確認してください)、この第三の場合には、b()の体内での最初の文は最も囲む範囲内のx の値を探します。そして、この範囲では、xは次の行に割り当てられます。ステートメントa = x+2しかない場合、xはほとんどの囲みスコープでは見つかりません。x = 1で、「next」囲みスコープにxがあります。あなたのコード内で何が起こっている

6

はPythonが見たときには、それがb関数内のスコープでxを再作成の代わりに、それはa関数内のスコープだとxを使用しているあなたのb()方法でx=3ラインだということです。

あなたのコードは、その後行くので:あなたが、内側には、それを参照する前にxスコープ定義する必要があると言っている

a = x+2 
    x = 3 

しかし、b関数内にxという割り当てを持たない場合、pythonは低いスコープのxを作成しようとせず、エラーをスローしません。

次のコードは、このことを説明します:

def a(): 
    x = 1 
    def b(): 
     x = 3 
     print (x) 

    def c(): 
     print (x) 

    b() 
    c() 
    print (x) 

a() 

をしかし、あなたがそうのように、関数内でそれを使用することができglobalとしてxを宣言した場合:

def a(): 
    global x 
    x = 1 

    def d(): 
     global x 
     x += 2 

    print (x) 
    d() 
    print (x) 

a() 

のPython 3にも追加されました囲みスコープから変数にアクセスできるようにするnonlocalキーワードは、次のようになります。

def a(): 
    x = 1 

    def d(): 
     nonlocal x 
     x += 2 

    print (x) 
    d() 
    print (x) 

a() 

globalの例と同じ結果が出力されます。 Get locals from calling namespace in Pythonへの答えを1として

あなたが使用することができます。

import inspect 

def a(): 
    x = 1 

    def d(): 
     frame = inspect.currentframe() 
     try: 
      print (frame.f_back.f_locals) 
     finally: 
      del frame 
    d() 

a() 

を関数のローカルスコープを取得するために、私は質問を読み逃した場合


発信者。

+0

Python 3が追加された内部関数で囲みスコープから既存の名前を再バインドできる 'nonlocal'キーワードです。 – Blckknght

+0

非常にセクシー!ありがたいことに感謝する価値があります。 – Serdalis

関連する問題