¿Por qué asignar a mis variables globales no funcionar en Python?
-
06-09-2019 - |
Pregunta
Estoy teniendo un problema terrible tratando de comprender reglas de alcance de Python.
Con el siguiente script:
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 lo inesperado (me) de salida de:
Before setA Value of a is 7 Inside setA, a is now 42 After setA Value of a is 7
Cuando yo esperaría que la última impresión del valor de una era de 42, no 7. ¿Cuál falto acerca de las reglas de alcance de Python para la determinación del alcance de las variables globales?
Solución
Las variables globales son especiales. Si intenta asignar a un a = value
variable dentro de una función, se crea una nueva variable local dentro de la función, incluso si hay una variable global con el mismo nombre. Para acceder lugar la variable global, agregar una declaración global
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
href="http://docs.python.org/reference/executionmodel.html#naming-and-binding" y vinculante para una explicación detallada de nombramiento de Python y normas de obligado cumplimiento.
Otros consejos
El truco para la comprensión de esto es que cuando se asigna a una variable, usando =, también se declara como una variable local. Así que en lugar de cambiar el valor de la variable a escala mundial, SETA (valor) en realidad establece una variable local (que pasa a llamarse a) el valor pasado.
Esto se hace más evidente si intenta imprimir el valor de una al comienzo de seta (valor) 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 esta Python le dará un error de útiles:
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
Esto nos dice que Python ha decidido que la función de seta (valor) tiene una variable local llamada A, que es lo que se altera cuando se asigna a ella en la función. Si no se asigna a una en la función (como con Impresión ()), entonces Python usa la variable A global.
Para marcar una variable tan global es necesario utilizar la palabra clave global en Python, en el ámbito que desee utilizar la variable global . En este caso que está dentro de la función de seta (valor). Así que 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 línea le dice a Python además que cuando se utiliza la variable a en la función de seta (valor) que se habla de la variable global, no una variable local.
Python no tiene un concepto de variables como otros idiomas. Tiene objetos que son "en algún lugar" y tiene referencias a estos objetos. = Se utiliza para asignar estos objetos para referencias en el actuales espacio de nombres.
Se crea un nombre de un espacio de nombres en el de la función de seta que se refiere al objeto al que se refiere valor.
dentro de la función, a es tratada como una variable local, es necesario definir
mundial a
dentro de la función
La ejecución de una función introduce una nueva tabla de símbolos utilizados para las variables locales de la función. De manera más precisa, todas las asignaciones de variables en una función de almacenar el valor en la tabla de símbolos local; mientras que las referencias a variables primero se ven en la tabla de símbolos local, a continuación, en las tablas de símbolos locales de funciones que encierran, a continuación, en la tabla de símbolos global, y por último en la tabla de una función de nombres. Por lo tanto, las variables globales no se pueden asignar directamente un valor dentro de una función (a no ser nombrado en una declaración global), aunque pueden ser referenciados.