5

Python 2.7では、次のコードを実行します。

def f():
    a = a + 1

f()

次の結果が得られます。

Traceback (most recent call last):
  File "test.py", line 4, in <module>
    f()
  File "test.py", line 2, in f
    a = a + 1
UnboundLocalError: local variable 'a' referenced before assignment

しかし、コードを以下に変更すると、次のようになります。

def f():
    a[0] = a[0] + 1

f()

別のエラーが発生します:

Traceback (most recent call last):
  File "test.py", line 4, in <module>
    f()
  File "test.py", line 2, in f
    a[0] = a[0] + 1
NameError: global name 'a' is not defined

Pythonaがローカル変数であると見なしているのにint、グローバルであると見なしているのはなぜlistですか?この背後にある理論的根拠は何ですか?

PS:私はこのスレッドを読んだ後に実験していました。

4

2 に答える 2

7

キーは、割り当てステートメントのドキュメントに記載されています。

単一のターゲットへのオブジェクトの割り当ては、次のように再帰的に定義されます。

ターゲットが識別子(名前)の場合(例a = a + 1

  • 名前が現在のコードブロックのグローバルステートメントに含まれていない場合:名前は現在のローカル名前空間のオブジェクトにバインドされます。
  • それ以外の場合:名前は現在のグローバル名前空間のオブジェクトにバインドされます。

すでにバインドされている場合、名前はリバウンドされます。これにより、以前に名前にバインドされたオブジェクトの参照カウントがゼロになり、オブジェクトの割り当てが解除され、そのデストラクタ(存在する場合)が呼び出される可能性があります。

..。

ターゲットがサブスクリプションの場合(例a[0] = a[0] + 1:参照のプライマリ式が評価されます。可変シーケンスオブジェクト(リストなど)またはマッピングオブジェクト(辞書など)のいずれかを生成する必要があります。次に、添え字式が評価されます。

f1では、Pythonは、ある値をaにバインドしていることを確認し、このスコープのステートメントでa使用されていないことを確認し、ローカル変数を準備します。global a次に、式の評価を試みa + 1、変数を検索して、初期化されaていないローカル変数を見つけます。これにより、がUnboundLocalError

f2では、Pythonは、変数のサブスクリプションに値を割り当てていることを確認しますa。ローカル名前空間でその変数を検索し、それを見つけることができません。次に、グローバル名前空間に到達するまで、非ローカル名前空間(クロージャ)をウォークアップします。グローバル名前空間での検索に失敗するとa、をスローしNameErrorます。

于 2013-03-24T03:33:46.353 に答える
-1

あなたはこのようなことをしようとできますか:

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

def g():
    a = 3
    f(a)

g()
于 2013-03-24T03:33:35.873 に答える