No se puede modificar un int global, pero puede modificar una lista. ¿Cómo?

LISTL = [] VAR1 = 0 def foo (): … VAR1 + = 1 … devuelve VAR1 …

Al llamar a foo() , recibo este error:

 UnboundLocalError: local variable 'VAR1' referenced before assignment 

Sin embargo, considere la lista LISTL

 >>> def foo(x): ... LISTL.append(x) ... return LISTL ... >>> foo(5) [5] 

Esto funciona como se esperaba. La pregunta es ¿por qué el anexo en una lista funciona pero no puedo cambiar el int?

Además, ¿es esta la forma correcta de declarar un global en Python? (Justo después de las declaraciones de importación)

El motivo de esta diferencia tiene que ver con la forma en que Python asigna un nombre a los nombres. Si está dentro de una definición de función ( def foo(): LISTL , y LISTL un nombre ( VAR1 o LISTL ), primero buscará en su espacio de nombres local, donde no encontrará nada, y luego buscará en el espacio de nombres de Módulo en el que se definió la función, hasta el espacio de nombres global hasta que encuentra una coincidencia o falla.

Sin embargo, ACCESAR un nombre y ASIGNAR un nombre son dos conceptos diferentes. Si está nuevamente dentro de la definición de su función y dice VAR1 = 2 , está declarando una nueva variable con el nuevo nombre local VAR1 dentro de la función. Esto tiene sentido si considera que, de lo contrario, se encontraría con todo tipo de colisiones de nombres si no existiera dicho espacio en el trabajo.

Cuando se agrega a una lista, simplemente se ACCEDE a la lista y luego se llama un método que cambia para cambiar su valor conceptual. Cuando usas do += , en realidad estás ASIGNANDO un valor a un nombre.

Si desea poder asignar valores a nombres definidos fuera del espacio de nombres actual, puede usar la palabra clave global . En ese caso, dentro de su función, primero diría global VAR1 , y de ahí el nombre VAR1 sería el nombre en el espacio de nombres externo, y cualquier asignación a este tendrá efecto fuera de la función.

Si asigna una variable dentro de una función, se asume que esa variable es local a menos que la declare global .