誰でも以下のコードの例外を説明できますか? display() の var サブを別の名前に変更した場合にのみ機能します。グローバル変数 sub もありません。どうしたの ?
def sub(a, b):
return a - b
def display():
sub = sub(2,1) // if change to sub1 or sth different to sub, it works
print sub
誰でも以下のコードの例外を説明できますか? display() の var サブを別の名前に変更した場合にのみ機能します。グローバル変数 sub もありません。どうしたの ?
def sub(a, b):
return a - b
def display():
sub = sub(2,1) // if change to sub1 or sth different to sub, it works
print sub
スコープ内で割り当てた変数はローカル変数として扱われます (宣言しない限りglobal
、または python3 ではnonlocal
)。これは、周囲のスコープで検索されないことを意味します。
同じエラーの簡単な例:
def a(): pass
def b(): a = a()
ここで、ここに含まれるさまざまなスコープを検討してください。
グローバル名前空間にはa
とが含まれていb
ます。
関数a
にはローカル変数が含まれていません。
関数b
には割り当てが含まれていますa
- これは、ローカル変数として解釈されa
、外側のスコープ (この場合はグローバル スコープ) から関数をシャドウすることを意味します。a
呼び出しの前に内部で定義されていないためb
、バインドされていないローカル変数であるため、UnboundLocalError になります。これは、次のように記述した場合とまったく同じです。
def b(): x = x()
これに対する解決策は簡単ですsub
。呼び出しの結果に別の名前を選択してください。
使用と割り当ての順序に違いはないことに注意することが重要です。次のように関数を記述した場合でもエラーが発生します。
def display():
value = sub(2,1) #UnboundLocalError here...
print value
sub = "someOtherValue" #because you assign a variable named `sub` here
これは、Python インタープリターが関数オブジェクトを作成するときに、ローカル変数のリストが生成されるためです。
これはもともとコメントでした。OPは、これが答えとして役立つことを発見しました。したがって、私はそれを答えとして再投稿しています
最初sub
は、関数です。すると、関数の戻り値になります。したがって、あなたが言うときprint sub
、Pythonはsub
あなたがどちらを参照しているのかわかりません。
編集:
まず、関数を定義しますsub
。これで、Pythonは何sub
であるかを認識します。
変数を作成してそれに割り当てようとすると(たとえばx = 2
)、Pythonはの右側にあるものを=
評価し、評価の値をの左側にあるものの値として割り当てます=
。したがって、右側のすべてが実際に計算する必要があります。
したがって、ステートメントがだった場合はx = x+1
、x
その行の前に値を割り当てた方がよいでしょう。以前に定義されx
たものは、の追加と互換性のあるタイプである必要があり1
ます。
しかし、関数であると仮定し、他の関数でx
呼び出される変数を作成し、x
それに関数で計算された値を割り当てようとすると、これは実際に参照しているx
Pythonを混乱させ始めます。x
これは実際にはこの答えを単純化しすぎており、Python関数で変数スコープとシャドウイングを説明するのにはるかに優れています。
使用される変数ごとに、Python はそれがローカル変数か非ローカル変数かを判断します。未知の変数を参照すると、非ローカルとしてマークされます。後でローカル変数と同じ名前を再利用することは、プログラマーのミスと見なされます。
次の例を検討してください。
def err():
print x # this line references x
x = 3 # this line creates a local variable x
err()
これにより、
Traceback (most recent call last):
File "asd.py", line 5, in <module>
err()
File "asd.py", line 2, in err
print x # this line references x
UnboundLocalError: local variable 'x' referenced before assignment
基本的に、Python はコード内の名前へのすべての参照を追跡します。行を読み取ると、print x
Python はそれx
が外側のスコープ (上位値またはグローバル) からの変数であることを認識します。ただし、 はx = 3
ローカルx
変数として使用されます。これはコードの不一致であるため、Python はUnboundLocalError
プログラマーの注意を引くために an を発生させます。
Python はコードの実行を開始し、最初に関数を取得します
def sub(a, b):
return a - b
したがって、このインタープリターを実行した後sub
、関数として取得します。次の行に来ると、それが見つかりました
def display():
sub = sub(2,1) // if change to sub1 or sth different to sub, it works
print sub
そのため、最初の行で関数が変数sub = sub (2, 1)
に変換されます。この関数から変数を返します。そのため、問題が発生します。sub
sub
sub