¿Por qué la asignación a mis variables globales no funciona en Python?
Estoy teniendo terribles problemas al tratar de comprender las reglas de alcance de Python.
Con el siguiente guión:
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()
Da el resultado inesperado (para mí) de:
Antes del conjunto A El valor de a es 7. Dentro de setA, a ahora es 42 Después del conjunto A El valor de a es 7.
Donde esperaría que la última impresión del valor de a fuera 42, no 7. ¿Qué me falta acerca de las reglas de alcance de Python para el alcance de las variables globales?
Las variables globales son especiales. Si intenta asignar una variable a = value
dentro de una función, crea una nueva variable local dentro de la función, incluso si hay una variable global con el mismo nombre. Para acceder a la variable global, agregue una global
declaración dentro de la función:
a = 7
def setA(value):
global a # declare a to be a global
a = value # this sets the global value of a
Consulte también Denominación y vinculación para obtener una explicación detallada de las reglas de denominación y vinculación de Python.
El truco para entender esto es que cuando asignas una variable, usando =, también la declaras como una variable local. Entonces, en lugar de cambiar el valor de la variable global a, setA(value) en realidad establece una variable local (que se llama a) con el valor pasado.
Esto se vuelve más obvio si intentas imprimir el valor de a al comienzo de setA(value) de esta manera:
def setA(value):
print "Before assignment, a is %d" % (a)
a = value
print "Inside setA, a is now %d" % (a)
Si intenta ejecutar este Python, obtendrá un error útil:
Rastreo (llamadas recientes más última): Archivo "scopeTest.py", línea 14, en establecerA(42) Archivo "scopeTest.py", línea 7, en setA print "Antes de la asignación, a es %d" % (a) UnboundLocalError: variable local 'a' a la que se hace referencia antes de la asignación
Esto nos dice que Python ha decidido que la función setA(value) tiene una variable local llamada a, que es lo que modificas cuando le asignas la función. Si no asigna a a en la función (como con printA()), Python usa la variable global A.
Para marcar una variable como global, debe usar la palabra clave global en Python, en el ámbito en el que desea usar la variable global . En este caso, eso está dentro de la función setA(valor). Entonces el guión se convierte en:
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()
Esta adición de una línea le dice a Python que cuando usas la variable a en la función setA(value) estás hablando de la variable global, no de una variable local.