Ámbito en Python
Aprende el ámbito en Python y la regla LEGB: ámbitos local, envolvente, global e incorporado, con ejemplos claros y las palabras clave global/nonlocal.
Entendiendo el Ámbito en Python
El ámbito determina dónde es visible un nombre de variable y cuánto tiempo existe. Cada nombre que creas — una variable, una función, una clase — pertenece exactamente a un ámbito. Cuando Python encuentra un nombre, busca en los ámbitos en un orden estricto hasta encontrarlo o lanzar un NameError.
Esta página cubre:
- Los cuatro niveles de ámbito y la regla de búsqueda LEGB
- Las palabras clave
globalynonlocal - Errores comunes: sombreado,
UnboundLocalErrory fuga de nombres - Cómo inspeccionar los ámbitos en tiempo de ejecución
La Regla LEGB
Python resuelve los nombres en cuatro capas, buscando desde la más interna hasta la más externa:
| Nivel | Significa | Qué contiene |
|---|---|---|
| L | Local | Nombres definidos dentro de la función actual |
| E | Enclosing (Envolvente) | Nombres en cualquier función envolvente (exterior), para funciones anidadas |
| G | Global | Nombres definidos en el nivel superior del módulo actual |
| B | Built-in (Incorporado) | Nombres precargados por Python — print, len, range, type, etc. |
Python se detiene en la primera coincidencia. Si no se encuentra ninguna coincidencia en ninguna capa, se lanza un NameError.
Ámbito Local
Un nombre es local cuando se asigna dentro de una función. Se crea cuando se llama a la función y se destruye cuando la función retorna. Los nombres locales son invisibles fuera de la función.
def greet():
message = "Hello, World!" # local variable
print(message) # accessible here
greet()
# Output: Hello, World!
print(message) # NameError: name 'message' is not definedPor qué importa el ámbito local
El ámbito local te permite usar nombres simples y descriptivos como total, result o i dentro de cada función sin que ninguno de ellos entre en conflicto entre sí ni con el código a nivel de módulo.
def calculate_area(radius):
pi = 3.14159 # local to this function
area = pi * radius ** 2
return area
def calculate_volume(radius, height):
pi = 3.14159 # completely separate local 'pi'
volume = pi * radius ** 2 * height
return volume
print(calculate_area(5)) # 78.53975
print(calculate_volume(5, 10)) # 785.3975Ambas funciones usan pi de forma independiente. No hay conflicto.
Ámbito Envolvente
Cuando una función se define dentro de otra función, la función interna puede leer nombres de la función externa (envolvente). Esta es la E en LEGB.
def outer():
color = "blue" # enclosing variable
def inner():
print(color) # reads from enclosing scope
inner()
outer()
# Output: blueLa función interna puede leer color sin ninguna palabra clave especial porque Python sube automáticamente al ámbito envolvente.
Modificar una variable envolvente con nonlocal
Leer una variable envolvente es automático, pero asignarle un valor requiere la palabra clave nonlocal. Sin ella, Python trata la asignación como la creación de una nueva variable local, no como la modificación de la envolvente.
def make_counter():
count = 0 # enclosing variable
def increment():
nonlocal count # declare intent to modify the enclosing 'count'
count += 1
return count
return increment
counter = make_counter()
print(counter()) # 1
print(counter()) # 2
print(counter()) # 3Cada llamada a counter() modifica la misma variable count. Este patrón es la base de las closures — consulta Python Closures para una explicación más profunda.
Ámbito Global
Los nombres definidos en el nivel superior de un módulo (fuera de cualquier función) son globales. Son accesibles desde cualquier parte del mismo módulo, incluso dentro de las funciones.
language = "Python" # global variable
def display_language():
print(language) # reads global without any keyword
display_language()
# Output: PythonModificar una variable global con global
Puedes leer una variable global desde dentro de una función sin ninguna palabra clave. Pero si quieres asignarle un valor, debes declararla con global primero:
total = 0 # global variable
def add_to_total(n):
global total # declare intent to modify the global
total += n
add_to_total(5)
add_to_total(3)
print(total) # 8Sin global total, la línea total += n lanzaría un UnboundLocalError porque Python trataría total como una variable local que aún no ha sido asignada.
Para más información sobre variables globales, consulta Python Global Variables.
Cuándo evitar global
El uso extensivo de global hace que el código sea más difícil de probar y razonar. Prefiere retornar valores desde las funciones y pasar los datos como argumentos. Reserva global para el estado genuino a nivel de módulo — banderas de configuración, contadores o cachés — y úsalo raramente.
Ámbito Incorporado
El ámbito incorporado contiene nombres que Python proporciona automáticamente. Están disponibles en cada módulo sin ninguna importación.
Los nombres incorporados comunes incluyen print, len, range, type, int, str, list, dict, set, tuple, open, input, max, min, sum, sorted, enumerate, zip y map.
No sombrear nombres incorporados
Dado que el ámbito incorporado se busca en último lugar, cualquier nombre local o global con la misma ortografía lo sombreará. Este es un error común:
# Bad: shadows the built-in 'list'
list = [1, 2, 3]
print(type(list)) # <class 'list'> — still works here
new = list([4, 5]) # TypeError: 'list' object is not callableElimina el nombre que hace el sombreado para restaurar el incorporado:
del list # remove the local/global shadowing name
new = list([4, 5]) # works again: [4, 5]El módulo incorporado está disponible como builtins si alguna vez necesitas acceder a él explícitamente:
import builtins
print(builtins.len([1, 2, 3])) # 3Errores Comunes
UnboundLocalError
El error de ámbito más frecuente en Python es leer un nombre antes de asignarlo dentro de una función cuando también existe una asignación a ese nombre en cualquier parte de la misma función:
x = 10
def bad_func():
print(x) # UnboundLocalError! Python sees x = 20 below
x = 20 # this makes 'x' local for the whole function
bad_func()Python decide en tiempo de compilación que x es local (porque se asigna en la función). El intento de leerla antes de la asignación lanza UnboundLocalError: local variable 'x' referenced before assignment.
Corrígelo declarando global x o no asignando a x dentro de la función.
Sombreado de variables
Una variable local que comparte un nombre con una global sombrea silenciosamente a la global. Esto suele ser intencional, pero puede causar errores sutiles cuando esperas estar leyendo la global:
x = 10 # global
def my_func():
x = 20 # local — shadows the global
print(x) # 20, not 10
my_func()
print(x) # 10 — global unchangedInspeccionar el Ámbito en Tiempo de Ejecución
Python expone el contenido del ámbito actual a través de dos funciones incorporadas.
locals() retorna un diccionario del ámbito local actual (o el espacio de nombres a nivel de módulo si se llama en el nivel superior):
def show_locals():
a = 1
b = "hello"
print(locals()) # {'a': 1, 'b': 'hello'}
show_locals()globals() retorna el diccionario del espacio de nombres global (a nivel de módulo):
language = "Python"
print("language" in globals()) # TrueEstas son útiles para depuración e introspección, pero no deben usarse para manipular variables dinámicamente en código de producción.
Ámbito y Funciones
Las funciones en Python son objetos y son en sí mismas nombres que viven en algún ámbito. Una función definida en la parte superior de un módulo es global; una función definida dentro de otra función es local a la función envolvente.
def outer():
def helper(): # helper is local to outer
return 42
return helper()
print(outer()) # 42
# helper() # NameError: helper is not defined hereConsulta Python Functions para ver cómo se definen las funciones, y Python Lambda para funciones anónimas que también obedecen la regla LEGB.
Referencia Rápida
| Palabra clave | Efecto |
|---|---|
| (ninguna) | Leer desde el ámbito envolvente más cercano mediante la búsqueda LEGB |
global x | Indica a la función actual que x hace referencia al nombre a nivel de módulo |
nonlocal x | Indica a la función actual que x hace referencia al nombre en la función envolvente más cercana |