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?

¿Fue útil?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top