Warum die Zuordnung meiner globalen Variablen nicht in Python arbeiten?
-
06-09-2019 - |
Frage
Ich habe schreckliche Mühe versuchen, Python Scoping-Regeln zu verstehen.
Mit dem folgende Skript:
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()
Gibt das Unerwartete (für mich) Ausgang:
Before setA Value of a is 7 Inside setA, a is now 42 After setA Value of a is 7
Wo ich wäre der letzte Druck des Wertes eines erwarte 42 zu sein, nicht 7. Was ich für das Scoping von globalen Variablen über Pythons Bereichsregeln bin fehle?
Lösung
Globale Variablen sind etwas Besonderes. Wenn Sie versuchen, innerhalb einer Funktion einer Variablen a = value
zuweisen, erstellt es eine neue lokale Variable in der Funktion, auch wenn es eine globale Variable mit dem gleichen Namen. Um stattdessen die globale Variable zuzugreifen, fügen Sie eine global
Anweisung innerhalb der Funktion:
a = 7
def setA(value):
global a # declare a to be a global
a = value # this sets the global value of a
Siehe auch Naming und Bindung für eine detaillierte Erklärung von Pythons Benennung und verbindliche Regeln.
Andere Tipps
Der Trick, um dies zu verstehen, ist, dass, wenn Sie ein Variablen zuweisen, mit =, Sie es auch als lokalem Variable deklarieren. Anstatt also den Wert der globalen Variablen eine Änderung setA (Wert) setzt eigentlich eine lokale Variable auf den Wert übergeben (das ist ein aufgerufen werden, geschieht).
Dies wird noch deutlicher, wenn Sie versuchen, den Wert eines zu Beginn des setA (Wert) wie so drucken:
def setA(value):
print "Before assignment, a is %d" % (a)
a = value
print "Inside setA, a is now %d" % (a)
Wenn Sie versuchen, dieser Python ausführen werden Sie einen hilfreichen Fehler:
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
Das sagt uns, dass Python hat entschieden, dass die setA (Wert) Funktion eine lokale Variable genannt, das ist, was Sie ändern, wenn Sie es in der Funktion zuweisen. Wenn Sie nicht zuordnen zu einem in der Funktion (wie bei druckenA ()) verwendet dann Python die globale Variable A.
Um eine Variable zu markieren, wie global die globale Schlüsselwort in Python verwenden müssen, in den Rahmen, die Sie die globale Variable verwenden möchten . In diesem Fall, der innerhalb des setA (Wert) Funktion ist. Also das Skript wird:
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()
Diese eine Zeile hinaus sagt Python, dass, wenn Sie die Variable a in der setA (Wert) Funktion, die Sie über die globale Variable sprechen, nicht eine lokale Variable.
Python hat kein Konzept von Variablen als anderen Sprachen. Sie haben Objekte, die „irgendwo“ und Sie haben Referenzen auf diese Objekte sind. = Wird verwendet, um diese Objekte zu Referenzen in der Strom Namensraum zuzuweisen.
Sie erstellen einen Namen ein im Namensraum der setA Funktion, die auf das Objekt bezieht sich auf welchen Wert bezieht.
innerhalb der Funktion, a als lokale Variable behandelt wird, müssen Sie definieren
global a
in der Funktion
Die Ausführung einer Funktion führt eine neue Symboltabelle für die lokalen Variablen der Funktion verwendet. Genauer gesagt, werden alle Variablenzuweisungen in einer Funktion, um den Wert in der lokalen Symboltabelle speichern; während Variablenreferenzen in der lokalen Symboltabelle, dann in den lokalen Symboltabellen der umgebenden Funktionen, dann in der globalen Symboltabelle und schließlich in der Tabelle der eingebauten Namen suchen zuerst. So können globale Variablen nicht direkt einen Wert innerhalb einer Funktion zugeordnet werden (es sei denn, in einer globalen Erklärung genannt), obwohl sie referenziert werden können.