1

誰でも以下のコードの例外を説明できますか? 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
4

4 に答える 4

2

スコープ内で割り当てた変数はローカル変数として扱われます (宣言しない限り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 インタープリターが関数オブジェクトを作成するときに、ローカル変数のリストが生成されるためです。

于 2012-10-01T12:51:47.110 に答える
1

これはもともとコメントでした。OPは、これが答えとして役立つことを発見しました。したがって、私はそれを答えとして再投稿しています

最初subは、関数です。すると、関数の戻り値になります。したがって、あなたが言うときprint sub、Pythonはsubあなたがどちらを参照しているのかわかりません。

編集

まず、関数を定義しますsub。これで、Pythonは何subであるかを認識します。

変数を作成してそれに割り当てようとすると(たとえばx = 2)、Pythonはの右側にあるものを=評価し、評価の値をの左側にあるものの値として割り当てます=。したがって、右側のすべてが実際に計算する必要があります。

したがって、ステートメントがだった場合はx = x+1xその行の前に値を割り当てた方がよいでしょう。以前に定義されxたものは、の追加と互換性のあるタイプである必要があり1ます。

しかし、関数であると仮定し、他の関数でx呼び出される変数を作成し、xそれに関数で計算された値を割り当てようとすると、これは実際に参照しているxPythonを混乱させ始めます。xこれは実際にはこの答えを単純化しすぎており、Python関数で変数スコープとシャドウイングを説明するのにはるかに優れています。

于 2012-10-01T12:26:58.633 に答える
1

使用される変数ごとに、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 xPython はそれxが外側のスコープ (上位値またはグローバル) からの変数であることを認識します。ただし、 はx = 3ローカルx変数として使用されます。これはコードの不一致であるため、Python はUnboundLocalErrorプログラマーの注意を引くために an を発生させます。

于 2012-10-01T13:23:48.450 に答える
-1

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)に変換されます。この関数から変数を返します。そのため、問題が発生します。subsubsub

于 2012-10-01T12:41:43.853 に答える