Para construir programas más grandes y robustos, es vital entender dónde "viven" y "mueren" nuestros datos, y qué tipo de bloques de código construimos para procesarlos.
Repasemos lo que ya sabemos: cuando declaramos una variable dentro de un bloque def, esa variable nace y muere exclusivamente allí adentro. Fuera de la función, es como si nunca hubiera existido. A esto lo conocemos como Variable Local.
El Ámbito (Scope) es justamente eso: la región o "contexto" del código donde una variable existe y desde donde puede ser leída o modificada.
Si creamos una variable en la raíz de nuestro programa (afuera de cualquier def), estamos creando una Variable Global. Todo el programa puede verla.
El problema: Si dentro de una función intentas modificar esa variable global, Python creerá por defecto que quieres crear una nueva variable local con el mismo nombre. Para decirle a la computadora "No crees una nueva, quiero alterar la global", usamos la instrucción global.
En el siguiente simulador de seguridad, cada vez que se llama a registrar_fallo(), la variable intentos debe aumentar en 1. Modifica el código utilizando global para que no lance un error (UnboundLocalError).
Hasta ahora, hemos llamado "funciones" a todos los bloques de código que definimos con def. Sin embargo, en Ciencias de la Computación existe una distinción técnica muy importante dependiendo de qué hace ese bloque al finalizar.
return). Su propósito es ejecutar acciones, como modificar variables globales o procesar parámetros externos.return. No debería alterar el exterior directamente.
Modifica una variable global destinada a guardar el resultado, pero no retorna nada al lugar donde fue invocado.
num_1 = 4 num_2 = 3 resultado = None def suma_proc(valor_1, valor_2): global resultado resultado = valor_1 + valor_2 suma_proc(num_1, num_2) print(resultado) # Imprime 7
Calcula el valor y lo devuelve directamente usando return. El resultado se guarda desde afuera.
num_1 = 4 num_2 = 3 def suma_func(valor_1, valor_2): return valor_1 + valor_2 resultado = suma_func(num_1, num_2) print(resultado) # Imprime 7
return, hacer ambas cosas a la vez se considera una mala práctica. Dificulta la lectura del código y el rastreo de errores. ¡Diseña tu bloque como Función o como Procedimiento, pero no ambos!
Convierte este código en un procedimiento puro. Modifica la variable global estado_sistema desde adentro usando global.
nonlocalEn Python es completamente válido crear funciones dentro de otras funciones. Al hacer esto, se genera un ámbito intermedio (Ámbito Anidado). Existen variables que son locales para la "función madre", pero desde el punto de vista de la "función hija", no son ni locales ni globales.
Para indicarle a la función interna que queremos modificar la variable de su función contenedora, utilizamos la palabra reservada nonlocal.
# 1. Ámbito Global variable_global = 10 def procedimiento_madre(): # 2. Ámbito Local de la madre (No es local para la hija) variable_intermedia = 20 def procedimiento_hija(): global variable_global nonlocal variable_intermedia # Ahora podemos modificarlas sin crear variables nuevas variable_global = 100 variable_intermedia = 200
Analiza el siguiente código extraído de la teoría. Ejecútalo y observa qué valores se imprimen al final. Presta mucha atención a la indentación y al flujo de llamadas.