なぜグローバル変数に割り当てると、Pythonで動作しませんか?
-
06-09-2019 - |
質問
私はひどいトラブルPythonのスコープ規則を理解しようとしたんだ。
次のスクリプト付きます:
a = 7
def printA():
print "Value of a is %d" % (a)
def setA(value):
a = value
print "Inside setA, a is now %d" %(a)
print "Before setA"
printA()
setA(42)
print "After setA"
printA()
(私に)の出力を予期しないを提供します
Before setA Value of a is 7 Inside setA, a is now 42 After setA Value of a is 7
私は42であることをの値の最後の印刷を期待する場合は、ない7.私は、グローバル変数のスコープのためのPythonのスコープ規則については不足しているのですか?
解決
グローバル変数は特別なものです。あなたは、関数の内部変数a = value
に割り当てようとする場合は、同じ名前のグローバル変数があっても、関数内に新しいローカル変数を作成します。代わりに、グローバル変数にアクセスするには、内部での global
ステートメントを追加機能:
a = 7
def setA(value):
global a # declare a to be a global
a = value # this sets the global value of a
また、の詳細な説明のためにに命名と結合見ますPythonの命名と結合ルールます。
他のヒント
これを理解するためのトリックは、あなたが=を使用して、変数に割り当てるときに、あなたはまた、ローカル変数としてそれを宣言することです。だからではなく、グローバル変数aの値を変化させる、セットA(値)は、実際に渡された値に(と呼ばれることを起こる)ローカル変数を設定します。
:あなたがセットAの開始時(値)の値を印刷しようとすると、このはそうのように、より顕著になります
def setA(value):
print "Before assignment, a is %d" % (a)
a = value
print "Inside setA, a is now %d" % (a)
あなたが実行しようとすると、このPythonはあなたに役立つエラーになります。
Traceback (most recent call last): File "scopeTest.py", line 14, in setA(42) File "scopeTest.py", line 7, in setA print "Before assignment, a is %d" % (a) UnboundLocalError: local variable 'a' referenced before assignment
これは、PythonがセットA(値)機能を使用すると、関数の中でそれに割り当てるときに変更するものである、というローカル変数を持っていることを決定しましたことを教えてくれる。あなたが関数内で()(printAのように)に割り当てない場合、Pythonはグローバル変数Aを使用します。
あなたはグローバル変数のを使用したい範囲にPythonでグローバルキーワード、のを使用する必要がグローバルとして変数をマークします。セットA(値)関数内であるこの場合。だから、このスクリプトは次のようになります。
a = 7
def printA():
print "Value of a is %d" % (a)
def setA(value):
global a
a = value
print "Inside setA, a is now %d" %(a)
print "Before setA"
printA()
setA(42)
print "After setA"
printA()
この1行の追加は、あなたがグローバル変数ではなく、ローカル変数について話しているセットA(値)関数内で変数aを使用するときというのPythonを伝えます。
Pythonは他の言語としての変数の概念がありません。あなたは「どこか」であるオブジェクトを持っていて、これらのオブジェクトへの参照を持っています。 = の現在のの名前空間の参照にこれらのオブジェクトを割り当てるために使用されます。
あなたは値が参照するオブジェクトを参照瀬田関数の名前空間で名前aを作成します。
関数内、のA のローカル変数として扱われ、あなたは
定義する必要があります
グローバル
関数内
関数の実行は、関数のローカル変数のために使用される新しいシンボルテーブルを紹介します。より正確には、関数内のすべての変数の割り当ては、ローカル・シンボル・テーブル内の値を格納します。変数の参照は、まず機能を囲んでのローカル・シンボル・テーブルには、グローバルシンボルテーブルに、そして最終的には内蔵の名前のテーブルには、ローカル・シンボル・テーブルに見える一方。これらは、参照することができるが、このように、グローバル変数は直接、(global文で指定されていない限り)関数内で値を割り当てることができません。