2009-07-28 13 views
3

、私は簡単な例を持ってPythonのスコープの問題

 
first local_var: None 
second local_var: local 

はしかし、私の実際の出力は次のようになります。

 
first local_var: 
Traceback (most recent call last): 
    File "test.py", line 13, in 
    func1() 
    File "test.py", line 10, in func1 
    func("first") 
    File "test.py", line 6, in func 
    print "local_var:", local_var 
UnboundLocalError: local variable 'local_var' referenced before assignment 

の私の理解Pythonのスコープ規則では、これが期待どおりに動作するはずです。私はこれが期待どおりに動作する他のコードを持っていますが、上記の簡単なケースでは動作しないコードフラグメントを減らすこともできません。だから私は困惑している。

答えて

9

それをローカルにしますfunc - printのステートメントでは「非常にry local "変数に代入されます。 jtbによると、Python 3ではこれをnonlocalで解決できますが、print文を使ってPython 2で作業していることはあなたのコードから明らかです。Python 2の従来の解決法は、割り当てがbarenameしたがって、あなたが望むよりも、変数は多くの地元のことはありません、例えば:

def func1(): 
    local_var = [None] 

    def func(args): 
     print args, 
     print "local_var:", local_var[0] 

     local_var[0] = "local" 

    func("first") 
    func("second") 

func1() 

割り当てインデックスにはbarenameにはないので、地域に影響を与えていない、とPython 2.2以来、それがために完全に許容可能です内包されている関数をに変更すると、このバージョンのすべての関数であるローカルにある変数にが参照されます()。をbarenamesに割り当てることは別の問題です変数にを参照するより)。

+0

ありがとうございます!これは、時には私が期待した動作をする理由を説明しています - 私は関数内でローカル変数を再割り当てしなかったとき(この場合はfunc())、すべてうまくいきました。あなたがそれを置くとき、それを割り当てることによって、「非常にローカルな」ものになりました。 –

1

Python 3.0より前では、関数は外部スコープ内の非グローバル変数に書き込むことができませんでした。 Python3はこれを可能にするnonlocalキーワードを導入しました。 func()の定義の先頭にnonlocal local_varを追加して、期待どおりの出力を得ることができます。 PEP 3104を参照してください。

Python 3で作業していない場合は、変数をグローバルにするか、何らかの形で関数に渡す必要があります。

1

事前に3.0をこの問題を解決するための標準的な方法は

def func1(): 
    local_var = [None] 

    def func(args): 
     print args, 
     print "local_var:", local_var[0] 

     local_var[0] = "local" 

    func("first") 
    func("second") 

func1()