1

次のモジュールがあります。

main.py

import my_import

my_import.a_func()

my_import.py

FOO = "foo"
BAR = []

def a_func():
   BAR.append("bar") #ok
   FOO = FOO + "foo" #UnboundLocalError: 
                     #local variable 'FOO' referenced before assignment

これはおそらくインポートによるものですが、どうですか?

[編集]

私が得た答えから、重要なのはインポートではありませんが、次のことはまだ奇妙です:

FOO = "foo"
BAR = []
def a_func():
    BAR.append("bar")
    print(FOO)
a_func()

--> 「foo」を出力します

FOO = "foo"
BAR = []
def a_func():
    BAR.append("bar")
    print(FOO)
    FOO = FOO + "foo"    
a_func()

--> 「UnboundLocalError: local variable 'FOO' referenced before assignment」で失敗し、「foo」を出力しません

インタープリターは、実際にコードを実行する前に、現在のスコープで割り当てを探しているようです。

4

3 に答える 3

5

Python が関数定義を解析するとき、次のような割り当てステートメントの左側にあるすべての変数名を記録します。

FOO = FOO + "foo"

このような変数名はすべてローカル変数として登録します。

関数が呼び出されたときではなく、関数定義が解析されたときに、割り当てステートメントによって Python がFOOローカル変数として登録されることを強調しておきます。そのため、後で関数が呼び出されたときに、代入の前に発生した参照でさえローカル変数を参照し、.FOOUnboundLocalError

def a_func():
    BAR.append("bar")
    print(FOO)       #<--- "Freaky" UnboundLocalError occurs here!
    FOO = FOO + "foo" 

内部a_funcでは、 FOO はローカル変数です。ステートメントがない場合print(FOO)、Python は代入に到達し、最初に右辺を評価します。変数名 に遭遇すると、それをローカル変数FOOとして認識し、その値は? と尋ねます。価値がない!したがって、 が発生します。UnboundLocalError

修正するには、内部がグローバル変数を参照global FOOすることを宣言するために使用します。FOOa_func

FOO = "foo"
BAR = []

def a_func():
   global FOO
   BAR.append("bar") #ok
   FOO = FOO + "foo" assignment

対照的に、BAR.append('bar')は Python が最初に変数を検索するため機能します。BAR形式の代入がなかったため、ローカル変数とは見なされませんBAR = ...。グローバル スコープで検索BARし、append メソッドを検索してから mutates しBARます。したがって、変更することはできますがBAR、代入することはできませんFOO(global FOOステートメントなしで)。

于 2013-04-04T12:47:40.327 に答える
2

いいえ、インポートとは関係ありません。対話型インタープリターであっても、単一のモジュールまたはスクリプトでも発生します。

最小限の例は

a = 1
def f():
    a = a + 1

この割り当てによりa、ローカル変数が作成されます。この場合、グローバルなものはシャドウされているため、アクセスできません。

globalグローバルなものを変更したい場合は、この状況を回避できます。

a = 1
def f():
    global a
    a = a + 1

または、変更をローカルに保持する場合は、別の名前のローカル変数を使用します。

a = 1
def f():
    b = a
    b = b + 1
于 2013-04-04T12:48:00.760 に答える