Comprender cómo se comporta una variable según el lugar donde se define es fundamental para escribir código limpio y libre de errores en Python. El alcance (scope) de una variable determina desde qué partes del programa puedes leer o modificar su valor, y dominarlo te evitará bugs difíciles de rastrear.
¿Qué diferencia hay entre una variable local y una variable global?
Una variable local es aquella que se crea dentro de una función y solo existe mientras esa función se ejecuta [0:30]. Al intentar acceder a ella fuera del cuerpo de la función, Python lanza un error indicando que la variable no está definida [1:25].
python
def mi_funcion():
x = 10 # variable local
print(f"El valor de la variable es {x}")
mi_funcion()
print(x) # NameError: name 'x' is not defined
Una variable global, en cambio, se declara en el primer nivel de indentación del archivo. Esto significa que cualquier función puede leer su valor sin necesidad de recibirlo como parámetro [2:15].
python
x = 100 # variable global
def mostrar_global():
print(f"El valor de la variable global es {x}")
mostrar_global()
print(x) # 100
La clave está en la indentación: el nivel en el que defines una variable determina su persistencia y visibilidad dentro del código.
¿Qué sucede cuando una función contiene otra función?
Python permite definir una función dentro de otra, lo que se conoce como inner function o función interna [3:30]. Al hacerlo, cada nivel de anidación puede tener su propia versión de la misma variable, y el valor que se imprime depende del alcance en el que te encuentres.
python
x = "global"
def funcion_externa():
x = "encapsulada"
def funcion_interna(): x ="local"print(x) # local
funcion_interna()print(x) # encapsulada
funcion_externa()
print(x) # global
Al ejecutar este código [5:10]:
Primero se imprime local, porque la función interna asigna su propio valor.
Después se imprime encapsulada, ya que al salir de la función interna se recupera el valor del nivel intermedio.
Finalmente se imprime global, el valor que persiste en todo el archivo.
Este comportamiento demuestra que cada nivel de indentación crea su propio espacio de nombres.
¿Cómo modificar una variable global o encapsulada desde una función?
¿Para qué sirve la palabra reservada global?
Cuando necesitas que una función no solo lea, sino que modifique el valor de una variable global, debes declararla explícitamente con la palabra reservada global [6:05].
python
x = 5 # variable global
def cambiar_valor():
global x
x = x + 3
print(f"Valor modificado: {x}")
cambiar_valor() # Valor modificado: 8
print(x) # 8
Sin la instrucción global x, Python crearía una variable local nueva en lugar de alterar la original. Al usarla, el cambio se refleja tanto dentro como fuera de la función [7:00].
¿Cuándo se utiliza nonlocal?
Existe un escenario intermedio: una variable que no es local ni global, sino que pertenece a una función envolvente. Para modificarla desde la función interna se emplea la palabra reservada nonlocal [7:50].
python
def funcion_envolvente():
x = "encapsulada"
def funcion_interna(): nonlocal x
x ="valor modificado"print(f"El valor en inner es {x}")funcion_interna()print(f"El valor afuera es {x}")
funcion_envolvente()
Al ejecutar [9:10]:
Dentro de la función interna, x cambia a "valor modificado".
Al salir al cuerpo de la función envolvente, el valor ya fue actualizado gracias a nonlocal.
Esto resulta útil cuando trabajas con closures o patrones donde funciones anidadas necesitan compartir estado sin recurrir a variables globales.
¿Cómo practicar estos conceptos?
Se propone un reto [10:10]: crear dos funciones que trabajen con un diccionario de empleados con las claves nombre, edad y salario.
La primera función recibe la información del diccionario.
La segunda analiza el salario y filtra empleados que superen cierto monto.
Debes aplicar correctamente variables locales y globales para gestionar los datos.
Prueba distintas combinaciones de global y nonlocal para ver cómo cambia el comportamiento del programa y comparte tu solución en los comentarios.
esto debería estar en las primeras clases después de variables.
Claro que no, es un tema que para que lo entiendas, debes saber funciones, funciones anidadas como trabajan, donde llamarlas, los closures son de este nivel, depronto un overview de escope pero no los closures.
si no sabes cómo ubicarlas, dónde y cuándo, qué sentido tiene aprender esto en las primeras clases?
Veo que todos usaron el bucle for, yo estoy tan acostumbrado a usar los métodos .map(), .filter() y otros de JS, que quise usar lo mismo con Python
employees =[{"name":"Juan","age":28,"salary":3500},{"name":"María","age":32,"salary":4200},{"name":"Carlos","age":25,"salary":3100},{"name":"Ana","age":40,"salary":5000},{"name":"Luis","age":30,"salary":3900},]def filter_salary():"""
Filtra a los empleados que ganan más de 4000USDSin parámetros
Retorna:list:Una lista de empleados
"""
returnlist(filter(lambda employe: employe['salary']>=4000, employees))print(f'Esta es la lista de todos los empleados: {employees}')print(f'Los empleados que ganan 4000 o más USD al mes son: {filter_salary()}')
Gracias por tu aporte
Quise usar lo aprendido en clases anteriores y traer datos de un archivo json
import json
withopen("Python_Avanzados\empleados.json", mode='r')asfile: empleados = json.load(file)def empleados_sueldo(lista_empleados, promedio): empleados_filtrados=[empleado for empleado in lista_empleados if empleado['salary']> promedio]return empleados_filtrados
print(empleados_sueldo(empleados,35000))
En Python, **scope** (alcance) se refiere a la visibilidad y duración de una variable en diferentes partes del código, mientras que **closures** (cierres) son funciones que recuerdan el entorno en el que fueron creadas, incluso después de que el entorno haya terminado de ejecutarse. Vamos a desglosar ambos conceptos, comenzando por las variables locales y globales.
### 1. Variables Locales y Globales
#### Variables Locales
Las variables locales son aquellas definidas dentro de una función. Solo son accesibles dentro de esa función y se destruyen una vez que la función termina de ejecutarse.
def funcion\_local():  variable\_local = 10 # Variable local  print("Dentro de la función:", variable\_local)funcion\_local()\# print(variable\_local)# Esto generará un error porque variable\_local no está definida aquí
#### Variables Globales
Las variables globales son aquellas definidas fuera de cualquier función. Son accesibles desde cualquier parte del código, incluyendo dentro de funciones. Sin embargo, para modificar una variable global dentro de una función, se debe usar la palabra clave global.
variable\_global =20# Variable globaldef funcion\_global():  global variable\_global # Indica que se va a usar la variable global  variable\_global += 5 # Modifica la variable global  print("Dentro de la función:", variable\_global)funcion\_global()print("Fuera de la función:", variable\_global)
### 2. Closures
Los closures son funciones anidadas que recuerdan el entorno en el que fueron creadas, incluso si su función contenedora ha terminado de ejecutarse. Esto es útil para crear funciones que mantienen el estado entre llamadas.
#### Ejemplo de Closure
def crear\_multiplicador(factor):  def multiplicar(numero):  return numero \* factor # factor es una variable no local  return multiplicarmultiplicador\_por\_2 = crear\_multiplicador(2)print(multiplicador\_por\_2(5))# Salida: 10multiplicador\_por\_3 = crear\_multiplicador(3)print(multiplicador\_por\_3(5))# Salida: 15
En este ejemplo:
- crear\_multiplicador es una función que devuelve otra función (multiplicar).
- multiplicar recuerda el valor de factor incluso después de que crear\_multiplicador ha terminado de ejecutarse.
- Cada vez que se llama a multiplicador\_por\_2 o multiplicador\_por\_3, se utiliza el valor de factor que se pasó cuando se creó el closure.
### Resumen de Alcance y Closures
- **Alcance**: Define donde una variable puede ser accedida (local, global, etc.).
- Las **variables locales** solo se pueden usar dentro de la función donde fueron declaradas.
- Las **variables globales** se pueden usar en cualquier parte del código.
- **Closures**: Permiten que una función "recuerde" el entorno en el que fue creada, manteniendo el acceso a variables no locales (que no están definidas dentro de ella) a través de su estado interno.
Estos conceptos son fundamentales para entender cómo funcionan las funciones en Python y cómo se puede gestionar el estado y la visibilidad de las variables en el código.
Este comentario vale Oro, lo explicaste perfecto, yo vengo de aprender C++ y Java en la universidad, así como Js y Php y me quedé pensando si los demás habían entendido la magnitud del asunto porque luego escribiendo código, nos les funciona algo y es por El scope muchas veces. Exelente aporte!
RETO CUMPLIDO 💚:
CODIGO:
#Crear dos funciones una con una lista de diccionarios#la otra funcion deve cevovler la lista de empleados que ganen cierto sueldo#Variable local , con los datos de empleadosempl =[{'name':'Juan','age':17,'Salario':2000},{'name':'Lucia','age':27,'Salario':8000},{'name':'Marta','age':57,'Salario':20000}]defempleados(): trabajdores = empl #Trae la variable con los datosdefmejor_sueldo():#Modifica los datos locales de empleadosnonlocal trabajdores #Modifica la variable local trabajdores =[p for p in trabajdores if p['Salario']>3000]#Da una lista con los que ganan mas de 3000print(trabajdores)#Me imprime los mejroes pagados mejor_sueldo()#Ejectua la subfuncion cuando se llame la funcion empleadosempleados()#Empieza a cargar el codigo que hay dentro
Buenas noches, compañeros y profesora.
Aquí mi solución y abajo de ella la explicación:
En realidad no es necesario utilizar dos funciones (es redundante), y gracias a la forma en cómo se comportan las listas en Python, es posible hacer referencia a ellas sin necesidad de utilizar la instrucción Global.
En efecto, si dentro de cualquier función (o anidación de estas), hacemos referencia a una lista, Python 2 y Python 3, entienden que es global. Y por lo tanto no es necesario especificar que lo sea.
def gan(lista:list,limite_salary:float):print([l for l in lista if l['salary']> limite_salary])
Perdon, quise poner como comentario, no responder tu comentario...
Mi solución al reto:
empleados =[{'name':'Iris','age':'43','salary':100},{'name':'Ivan','age':'45','salary':200},{'name':'Andres','age':'25','salary':300},{'name':'Nohelia','age':'21','salary':400},{'name':'Samuel','age':'27','salary':500},{'name':'David','age':'33','salary':600},{'name':'Sarahi','age':'30','salary':700},{'name':'Jesus','age':'54','salary':800},{'name':'Haydee','age':'34','salary':900},{'name':'Francisco','age':'43','salary':1000}]# Variable globaldefempleados_con_mejor_sueldo(empleados,sueldo): empleados_superan_sueldo =[]# Variable local empleados_superan_sueldo =[empleado["name"]for empleado in empleados if empleado["salary"]>= sueldo]return empleados_superan_sueldo
sueldo =800print(f'Los empleados con suledo superior a {sueldo} son: {empleados_con_mejor_sueldo(empleados, sueldo)}')
def gan(lista:list,limite_salary:float):print([l for l in lista if l['salary']> limite_salary])
compañero, lo hice igual que tu, no sé por qué todo el mundo se complicó con algo tan complejo.
employees =[{"name":"John Doe","age":30,"salary":1000},{"name":"Jane Doe","age":25,"salary":900},{"name":"Bob Smith","age":35,"salary":1500},{"name":"Alice Johnson","age":40,"salary":2000}]salary_min =[employed for employed in employees if employed["salary"]>=1499]print(salary_min)
Yo me compliqué un poco, pero fue tratando de cumplir con las condiciones que se habían puesto en el ejercicio. Pensé que así tocaba, pero en realidad nadie siguió esas condiciones :S
employees =[{"name":"Jose Emmanuel","age":39,"salary":55000},{"name":"Maria Alejandra","age":40,"salary":58000},{"name":"Carlos Ramirez","age":28,"salary":48000},{"name":"Ana Gutierrez","age":32,"salary":51000},{"name":"Luis Fernandez","age":45,"salary":62000},{"name":"Gabriela Torres","age":27,"salary":47000},{"name":"Ricardo Mendoza","age":35,"salary":54000},{"name":"Sofia Martinez","age":30,"salary":50000},{"name":"Andres Lopez","age":42,"salary":60000},{"name":"Valeria Castillo","age":29,"salary":49000},]def search_emp_salary(lista,salary):"""
Obtiene el listado de empleados que ganan mas de un cierto salario
Parametros: lista Dict: diccionario con los datos de los empleados
salary integer: monto del salario a buscar
Salida: listado de empleados que gana mas de cierto salario
"""
employees=[emp for emp in lista if emp['salary']>salary] def list_emp_salary():print(f"Los empleados con mayor salario a {salary} son :")for i inemployees:print(f"Name: {i['name']} Age:{i['age']}")list_emp_salary()search_emp_salary(employees,55000)
employes_filtered =[]def filter_salary(employees): global employes_filtered
salary_max_input =int(input("Ingrese el salario maximo para filtrar: "))for employee inemployees:if employee["salary"]>= salary_max_input: employes_filtered.append(employees)return employees
employees =[{"name":"John","age":30,"salary":1000},{"name":"Jane","age":25,"salary":2000},{"name":"Jim","age":35,"salary":3000},]print(filter_salary(employees))
Creo que fuera mas claro si el ejemplo lo fuera dejado de esta forma.x = 100
def local_function(): x = 10 print(f'El valor de la variable local es: {x}')
def show_global(): print(f'El valor de la variable global es: {x}')
local_function()show_global()print('Global:', x)
x =100def local_function(): x =10print(f'El valor de la variable local es: {x}')def show_global():print(f'El valor de la variable global es: {x}')local_function()show_global()print('Global:', x)```Así puedes notar al llamar la función con la variable local no afecta la variable global aunque se este llamando antes.
Resultado:
`El valor de la variable local es:10``El valor de la variable global es:100``Global:100`
RETO: Aquí va una posible solución al reto. Sigo trabajando en el principio de simplicidad y eficiencia del código, así que a seguir!!!
# -------- RETO --------employees =[{"name":"Jose","age":30,"salary":2800},{"name":"Marcos","age":25,"salary":3500},{"name":"Carli","age":28,"salary":4200},{"name":"Maria","age":42,"salary":5600},{"name":"Gabriel","age":18,"salary":1500},]defpaid_employees(employees):"""
Busca los mejores empleados en el diccionario y los guarda en una lista
Input: Lista de diccionarios de los empleados
Output: Empleados con mejor pago
""" best_paid =[]for i in employees:if i['salary']>3000: best_paid.append(i['name'])# guarda los nombres de los mejores pagos en la lista best_paid.sort()print(f'Los empleados que más ganan son {best_paid}')paid_employees(employees)
defrecibir_empleados(lista_empleados):return lista_empleados
defempleados_con_sueldo_mayor(lista_empleados, sueldo_minimo):return[empleado for empleado in lista_empleados if empleado["salary"]> sueldo_minimo]# Ejemplo de usoempleados = recibir_empleados([{"name":"Ana","age":28,"salary":2500},{"name":"Luis","age":35,"salary":3200},{"name":"Carlos","age":40,"salary":1800},{"name":"Marta","age":30,"salary":4000},])filtrados = empleados_con_sueldo_mayor(empleados,2000)print(filtrados)
"""
Code that filters employee names based on salary greater than 50000."""
employees_filtered =[]def get_employee(name, salary):for employee inemployees:if employee["salary"]>50000: employees_filtered.append(employee)return employees_filtered
employees =[{"name":"John","salary":60000},{"name":"Jane","salary":45000},{"name":"Doe","salary":70000},{"name":"Alice","salary":30000},]resultado =get_employee(employees,50000)print(resultado)
Usa locales por defecto en tus funciones (datos de cálculo, filtros temporales).
Usa globales solo para constantes o pequeños estados globales muy claros (paths base, parámetros comunes, contadores de alto nivel).
gracias a "Dulce Hermosillo" me guie tambien del as clases pasada
import json
deffilter_salary(list_employees): most_salary=list_employees
defmejor_sueldo():nonlocal most_salary
most_salary=[ p for p in most_salary
if p['salary']>80000] mejor_sueldo()for employee in most_salary:print(f"Employee: {employee['name']}, Salary: {employee['salary']}")withopen('employees.json', mode='r')asfile: list_employees=json.load(file)""""
for employee in list_employees:
print(f"Employee: {employee['name']}, Salary: {employee['salary']}")
"""filter_salary(list_employees)