Lección 19 de 45 · Funciones

Ámbito de variables

Aprende dónde vive cada nombre para que una función no dependa de variables ocultas ni cambie datos inesperadamente.

Paso a pasoMarcos de nombresAvanza a tu ritmo
Índice · Lección 19/45
Los nombres no viven en todas partes

Cuando una función empieza a tener variables propias aparece una pregunta nueva: «¿desde qué parte del programa puedo usar este nombre?».

El ámbito —scope— responde a esa pregunta. Entenderlo evita depender de variables que cambian «por arte de magia».

Evidencia de aprendizaje

Localizar en qué ámbito existe cada nombre y predecir qué valor se verá dentro y fuera de una función.

Imagina cada función como una pequeña habitación

Una variable local
def preparar_saludo():
    mensaje = "Hola"
    return mensaje

print(preparar_saludo())

mensaje se crea dentro de la función. Es un nombre local: pertenece a ese contexto de ejecución. Fuera de la función no deberías intentar usarlo directamente.

La forma de sacar información de esa «habitación» no es conservar todas sus variables, sino devolver el valor que necesitas.

El mismo nombre puede existir dentro y fuera sin ser la misma variable

Dos ámbitos
mensaje = "fuera"

def cambiar_mensaje():
    mensaje = "dentro"
    print(mensaje)

cambiar_mensaje()
print(mensaje)

Primero verás dentro y después fuera. La asignación local no reemplaza automáticamente el nombre exterior.

Cuando veas una variable dentro de una función: empieza suponiendo que es local. Después comprueba si llega como parámetro o si se está leyendo desde fuera.

Los parámetros hacen visibles las dependencias

Compara estas dos ideas:

Dependencia explícita
def calcular_total(precio, impuesto):
    return precio + precio * impuesto

print(calcular_total(100, 0.21))

Al mirar la cabecera ya sabes qué necesita la función. Eso suele ser preferible a hacer que la función dependa de varias variables globales dispersas por el archivo.

Para después: existe global

global permite reasignar un nombre del ámbito global desde una función, pero no lo necesitas para resolver los problemas de este bloque. Prioriza parámetros y return: hacen visibles las dependencias y reducen cambios inesperados.

Coloca cada nombre en su marco

Marco globalmensaje = "fuera"
Marco de crear_mensajenombre = "Luna"mensaje = "Hola, Luna"

Dos nombres iguales pueden existir en marcos distintos. La pregunta útil no es “¿cuánto vale mensaje?”, sino “¿qué mensaje es visible aquí?”.

Completa la variable local sin tocar la global. La salida debe demostrar que cada ámbito conserva su propio valor.

Salida esperada
Hola, Luna
fuera
scope.py
La salida aparecerá aquí.

Necesito una pista
  • Dentro de la función construye un string usando el parámetro nombre.
  • No reasignes la variable global.
Ver una solución razonada
mensaje = "fuera"

def crear_mensaje(nombre):
    mensaje = f"Hola, {nombre}"
    return mensaje

print(crear_mensaje("Luna"))
print(mensaje)

Cuando un valor cambia y no sabes quién lo tocó

Esa sensación suele ser una señal de demasiado estado compartido. Reduce la búsqueda: identifica qué función necesita el dato, pásaselo como argumento y haz que devuelva un resultado. Cuantas menos funciones modifiquen variables externas, más fácil será razonar sobre el programa.

El objetivo no es memorizar LEGB

Más adelante puedes estudiar con detalle el orden de resolución de nombres de Python. Ahora basta con dominar una decisión práctica: lo que una función necesita debería verse, siempre que sea posible, en sus parámetros; lo que produce debería salir por return.

Puedes entrar en lambda cuando…

puedes explicar por qué una variable creada dentro de una función no debería convertirse automáticamente en una variable compartida por todo el programa.