Alcance de variables en Python: entiende la regla LEGB

Publicado el: 11/07/2026
Tempo de leitura: 5 minutos
Logo do Python com as palavras global e local

El alcance de una variable determina en qué partes del programa puede utilizarse un nombre y qué valor encuentra Python cuando existen nombres iguales en diferentes niveles. Comprender esta regla evita errores como NameError, cambios inesperados en variables globales y cierres que recuerdan valores distintos de los esperados. Python resuelve los nombres siguiendo la regla LEGB: Local, Enclosing, Global y Built-in.

Este tema aparece constantemente al crear funciones en Python, escribir decoradores, utilizar funciones lambda y diseñar funciones flexibles con *args y **kwargs.

Qué es un espacio de nombres

Un espacio de nombres relaciona identificadores con objetos. El módulo tiene un espacio global, cada llamada de función crea un espacio local y Python mantiene otro espacio con nombres integrados como len, print y sum. Cuando escribes un nombre, el intérprete busca dónde está definido.

La regla LEGB

Python busca en este orden:

  1. Local: nombres definidos dentro de la función actual.
  2. Enclosing: nombres de funciones externas que contienen a la función actual.
  3. Global: nombres definidos en el módulo.
  4. Built-in: nombres integrados del lenguaje.

La búsqueda termina en el primer nivel donde encuentra el nombre.

Alcance local

def mostrar_precio():
    precio = 50
    print(precio)

mostrar_precio()

precio existe durante la llamada a mostrar_precio(). Fuera de la función no está disponible:

print(precio)  # NameError

Cada llamada crea un nuevo espacio local.

Parámetros como variables locales

def calcular_total(precio, cantidad):
    subtotal = precio * cantidad
    return subtotal

precio, cantidad y subtotal son locales. Los argumentos entregados pueden referirse a objetos creados fuera, pero los nombres de los parámetros pertenecen a la función.

Alcance global

impuesto = 0.21

def calcular(precio):
    return precio * (1 + impuesto)

La función no define impuesto, por lo que Python lo encuentra en el módulo. Leer una variable global es posible sin ninguna declaración especial.

Asignar crea un nombre local

Si una función asigna un nombre, Python normalmente lo considera local en toda la función:

contador = 0

def incrementar():
    contador = contador + 1
    return contador

Este código produce UnboundLocalError. Como existe una asignación a contador, Python trata el nombre como local, pero intenta leerlo antes de que tenga un valor local.

Usar global

contador = 0

def incrementar():
    global contador
    contador += 1
    return contador

global indica que las asignaciones deben afectar al nombre del módulo. Funciona, pero crea estado compartido difícil de probar y mantener. Para la mayoría de aplicaciones es preferible devolver un valor, usar una clase o encapsular el estado.

def incrementar(contador):
    return contador + 1

contador = incrementar(contador)

Alcance enclosing

Una función interna puede leer variables de la función externa:

def crear_saludo(prefijo):
    def saludar(nombre):
        return f"{prefijo}, {nombre}"
    return saludar

hola = crear_saludo("Hola")
print(hola("Ana"))

La función saludar conserva acceso a prefijo incluso después de que crear_saludo termina. Este comportamiento se llama cierre o closure.

Modificar una variable externa con nonlocal

def crear_contador():
    valor = 0

    def incrementar():
        nonlocal valor
        valor += 1
        return valor

    return incrementar

contador = crear_contador()
print(contador())
print(contador())

nonlocal busca el nombre en una función contenedora, no en el módulo global. Si no existe una vinculación externa válida, se produce SyntaxError.

Objetos mutables y alcance

No necesitas global para modificar el contenido de un objeto global, porque no reasignas el nombre:

registros = []

def agregar(registro):
    registros.append(registro)

Aunque sea válido, sigue existiendo estado compartido. El comportamiento suele ser más claro cuando la lista se pasa como argumento:

def agregar(registros, registro):
    registros.append(registro)

Sombrear nombres

Una variable local puede ocultar un nombre global:

estado = "global"

def ejemplo():
    estado = "local"
    print(estado)

 ejemplo()

Dentro de la función se imprime local; fuera continúa existiendo global. Este sombreado es legal, pero puede confundir si el nombre representa conceptos distintos.

No sobrescribas nombres integrados

list = [1, 2, 3]

# Ahora list ya no se refiere al tipo integrado
# nueva = list("abc")  # TypeError

Evita nombres como list, str, sum, id o input. Puedes recuperar el nombre eliminando la variable, pero es mejor elegir un identificador descriptivo desde el inicio.

Comprensiones y su alcance

En Python 3, la variable de una comprensión no se filtra al alcance exterior:

cuadrados = [numero ** 2 for numero in range(5)]
# print(numero)  # NameError

Esto evita sobrescribir accidentalmente un nombre existente.

El problema de enlace tardío en cierres

Este patrón sorprende a muchos desarrolladores:

funciones = []

for numero in range(3):
    funciones.append(lambda: numero)

print([funcion() for funcion in funciones])

Las lambdas buscan numero cuando se ejecutan, después de terminar el bucle, por lo que todas suelen devolver el último valor. Puedes capturarlo mediante un argumento predeterminado:

funciones = []

for numero in range(3):
    funciones.append(lambda numero=numero: numero)

Cada función guarda el valor de esa iteración.

Variables de módulo e importaciones

Cada módulo tiene su propio espacio global. Una variable global no es universal para todo el programa; es global dentro de su módulo. Importar con from modulo import nombre crea una vinculación en el módulo importador. Para configuraciones compartidas, evita depender de reasignaciones implícitas y define una interfaz clara.

Inspeccionar espacios de nombres

locals() devuelve una representación del espacio local y globals() del global:

configuracion = "produccion"

def inspeccionar(valor):
    temporal = valor * 2
    print(locals())

print("configuracion" in globals())

No modifiques el diccionario devuelto por locals() esperando que cambie variables locales de forma confiable. Utilízalo principalmente para inspección y depuración.

Diseño sin globales mutables

Las funciones más fáciles de probar reciben datos y devuelven resultados:

def calcular_descuento(precio, porcentaje):
    return precio * porcentaje

Cuando necesitas conservar estado, una clase suele ser explícita:

class Contador:
    def __init__(self):
        self.valor = 0

    def incrementar(self):
        self.valor += 1
        return self.valor

Así el estado pertenece a una instancia y no a todo el módulo.

Diagnosticar UnboundLocalError

Cuando aparece UnboundLocalError, busca una asignación al mismo nombre dentro de la función. Decide si realmente querías una variable local, un parámetro, un retorno, nonlocal o, en casos excepcionales, global. No añadas global automáticamente sin entender el diseño.

La sección de nombres y vinculaciones del modelo de ejecución describe las reglas formales de alcance. El tutorial oficial sobre scopes y namespaces ofrece ejemplos de global y nonlocal.

Errores frecuentes

Los problemas habituales son reasignar una global sin declararla, abusar de global, confundir mutación con reasignación, ocultar funciones integradas y crear lambdas en un bucle sin capturar el valor. También es frecuente creer que una variable global pertenece a todos los módulos o que una variable local persiste entre llamadas.

Conclusión

La regla LEGB explica cómo Python resuelve cada nombre: primero local, luego funciones contenedoras, después el módulo y finalmente los nombres integrados. Entender la diferencia entre leer, reasignar y modificar objetos permite evitar NameError y UnboundLocalError. Siempre que sea posible, pasa datos como argumentos, devuelve resultados y encapsula el estado en objetos en lugar de depender de globales mutables.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Operações matemáticas usando o módulo math em Python
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    Módulo math en Python: operaciones matemáticas esenciales

    Aprende el módulo math en Python: raíces, potencias, redondeos, trigonometría, logaritmos, constantes, isclose y ejemplos prácticos.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    Geração de números aleatórios seguros usando secrets em Python
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    Módulo secrets en Python: números y tokens seguros

    Aprende secrets en Python para generar contraseñas, códigos y tokens seguros con randbelow, choice, token_hex, token_urlsafe y compare_digest.

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026
    Uso do operador walrus para atribuições inline em Python
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    Operador walrus en Python: guía con ejemplos

    Aprende el operador walrus := en Python: condiciones, while, comprensiones, lectura por bloques, regex, alcance y buenas prácticas.

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026
    Uso da função zip para combinar listas em Python
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    zip() en Python: combina listas e iterables correctamente

    Aprende zip() en Python para combinar listas, crear diccionarios, usar strict, zip_longest, desempaquetar valores y evitar pérdidas silenciosas.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    Uso do módulo time para controlar tempo em scripts Python
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    Módulo time en Python: pausas, timestamps y rendimiento

    Aprende el módulo time en Python: timestamps, sleep, monotonic, perf_counter, struct_time, strftime y buenas prácticas para medir tiempo.

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026
    Introdução ao módulo sys para iniciantes em Python
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    Módulo sys en Python: guía práctica para principiantes

    Aprende el módulo sys en Python: argv, exit, version, platform, path, flujos estándar, tamaño de objetos y buenas prácticas.

    Ler mais

    Tempo de leitura: 6 minutos
    11/07/2026