Python では、関数はデータであり、型付けは動的です。これは、次の行が有効な Python であることを意味します。
def func(x):
return x + 3
func = 3
func
intになりました。元の関数func
は参照されなくなりました。もともと関数だったという事実func
は、将来どのような種類のデータを割り当てることができるかには関係ありません。(これが「動的型付け」の意味です。)
したがって、静的型付けがなく、「関数」が有効なデータ型であるため、Python インタープリターが関数と同じ名前で参照されるデータを区別することは意味がありません。したがって、特定のスコープ内で、同じ非修飾変数名を使用して 2 つの異なることを意味する方法はありません。
あなたの特定のケースでは、xplus1
関数のコードが何かを意味する場合、それは「の値を計算してその値を変数にxplusy(x,1)
代入し、それによってfunctionへの参照を失う」ことを意味します。ただし、関数のスコープ内では、インタープリターはそのスコープ外の変数への代入を許可しないため、代入ステートメントを記述することで、新しいローカル変数を導入していると想定します。ただし、ローカル変数はまだ定義されていないため、それを呼び出そうとすると失敗します。グローバルに定義された関数はフォールバックとして呼び出されません。これも、修飾されていない 2 つの名前を同一にして、同じスコープ内の異なるデータを指すことができないためです。xplusy
xplusy
xplusy
xplusy(x,1)
「1つのスコープ内で変数名が重複しない」ルールを示す別の例(実際には、この回答を作成しようとしてプロンプトをいじっているときに発見しただけです):
>>> def f1():
... a = xplusy(3,4)
... xplusy = 5
... print xplusy
...
>>> f1()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in f1
UnboundLocalError: local variable 'xplusy' referenced before assignment
>>> def f1():
... a = xplusy(3,4)
... print a
...
>>> f1()
7
これは、一意の名前を必要とするステートメントではなく、実際にはscopeであることを示しています。
編集: これは、これおよびその他のスコープ関連の動作を説明する非常にクールな投稿です: http://me.veekun.com/blog/2011/04/24/gotcha-python-scoping-closures/