El ámbito (scope) de una variable es el contexto en el que es accesible. En Python hay 4 ámbitos principales que se pueden recordar con el principio LEGB:
La palabra clave global permite modificar una variable declarada a nivel global desde dentro de la función.
def foo(): global my_var my_var = 10 # modifica la variable global
Sin global dentro de la función, la variable se considera local, incluso si existe un nombre en el ámbito externo.
"¿Qué imprimirá el siguiente código?"
x = 10 def func(): x = 20 func() print(x)
Respuesta:
Imprimirá 10, porque dentro de la función se crea una nueva variable local x, la global no se modifica.
Historia
En el manejador de comandos de un bot querían almacenar un contador global, pero olvidaron sobre global:
counter = 0 def increment(): counter += 1 # UnboundLocalError: variable local 'counter' referenciada antes de la asignación
El error es porque el intérprete considera que counter es una variable local (ya que dentro de la función se le está asignando un valor), y no global.
Historia
En funciones anidadas olvidaron que sin la palabra clave nonlocal, la variable oculta crea un ámbito local:
def outer(): x = 0 def inner(): x += 1 # UnboundLocalError, x es considerado local en inner
Correctamente:
def outer(): x = 0 def inner(): nonlocal x x += 1
Historia
Escribieron una línea:
x = 5 y = (lambda: (x := x + 1))() # SyntaxError en Python < 3.8, o UnboundLocalError más tarde
Olvidaron la diferencia de ámbito para la expresión y lambda. No todas las construcciones admiten asignaciones dentro de lambda, dependiendo de la versión de Python.