Por qué el alcance variable puede mejorar o deshacer su flujo de trabajo de ciencia de datos | de Clara Chong | enero de 2025

Comencemos el 2025 escribiendo juntos un código limpio

Imagen por hincharse de desempaquetar

Cuando estás inmerso en la creación rápida de prototipos, es tentador omitir el alcance limpio o reutilizar nombres de variables comunes (hola, df!), pensando que ahorrará tiempo. Pero esto puede provocar errores furtivos que interrumpan su flujo de trabajo.

¿La buena noticia? Escribir código limpio y bien definido no requiere esfuerzo adicional una vez que se comprenden los principios básicos.

Analicémoslo.

Piense en una variable como un contenedor que almacenará cierta información. El alcance se refiere a la región de su código donde se puede acceder a una variable.

El alcance evita cambios accidentales al limitar dónde se pueden leer o modificar las variables. Si se puede acceder a todas las variables desde cualquier lugar, deberá realizar un seguimiento de todas ellas para evitar sobrescribirlas accidentalmente.

En Python, el alcance está definido por el regla LEGBque significa: Local, envolvente, global e integrado..

Alcance en Python, denominado LEGB (por el autor)

Ilustremos esto con un ejemplo.

# Global scope, 7% tax
default_tax = 0.07

def calculate_invoice(price):
# Enclosing scope
discount = 0.10
total_after_discount = 0

def apply_discount():
nonlocal total_after_discount

# Local scope
tax = price * default_tax
total_after_discount = price - (price * discount)
return total_after_discount + tax

final_price = apply_discount()
return final_price, total_after_discount

# Built-in scope
print("Invoice total:", round(calculate_invoice(100)[0], 2))

1. Ámbito local

Las variables dentro de una función están en el ámbito local. Sólo se puede acceder a ellos dentro de esa función.

En el ejemplo, tax es una variable local dentro apply_discount. No es accesible fuera de esta función.

2. Alcance adjunto

Estos se refieren a variables en una función que contiene un anidado función. Estas variables no son globales pero se puede acceder a ellas mediante la función interna (anidada). En este ejemplo, discount y total_after_discount son variables en el ámbito adjunto de apply_discount .

El nonlocal palabra clave:

El nonlocal palabra clave se utiliza para modificar variables en el ámbito adjunto, no solo leerlos.

Por ejemplo, supongamos que desea actualizar la variable total_after_discountque está en el ámbito adjunto de la función. Sin nonlocalsi asignas a total_after_discount dentro de la función interna, Python lo tratará como una nueva variable local.efectivamente sombra la variable exterior. Esto puede introducir errores y comportamientos inesperados.

3. Alcance global

Variables que se definen fuera de todas las funciones y accesible en todas partes.

El global declaración

Cuando declaras una variable como global Dentro de una función, Python la trata como una referencia a la variable fuera de la función. Esto significa que los cambios afectarán a la variable en el ámbito global.

Con el global palabra clave, Python creará una nueva variable local.

x = 10  # Global variable

def modify_global():
global x # Declare that x refers to the global variable
x = 20 # Modify the global variable

modify_global()
print(x) # Output: 20. If "global" was not declared, this would read 10

4. Alcance incorporado

Se refiere a las palabras clave reservadas que Python usa para sus funciones integradas, como print , def , round etcétera. Se puede acceder a este en cualquier nivel.

Ambas palabras clave son cruciales para modificar variables en diferentes ámbitos, pero se usan de manera diferente.

  • global: Se utiliza para modificar variables en el ámbito global.
  • nonlocal: Se utiliza para modificar variables en el ámbito adjunto (no global).

El sombreado de variables ocurre cuando una variable en un ámbito interno oculta una variable de un ámbito externo.

Dentro del alcance interno, todas las referencias a la variable apuntarán a la variable interna, no a la externa. Esto puede generar confusión y resultados inesperados si no tiene cuidado.

Una vez que la ejecución regresa al alcance externo, la variable interna deja de existir y cualquier referencia a la variable apuntará a la variable de alcance externo.

He aquí un ejemplo rápido. x se sombrea en cada ámbito, lo que da como resultado diferentes resultados según el contexto.

#global scope
x = 10

def outer_function():
#enclosing scope
x = 20

def inner_function():
#local scope
x = 30
print(x) # Outputs 30

inner_function()
print(x) # Outputs 20

outer_function()
print(x) # Outputs 10

Un concepto similar al sombreado de variables, pero esto ocurre cuando una variable local redefine o sobrescribe un parámetro pasado a una función.

def foo(x):
x = 5 # Shadows the parameter `x`
return x

foo(10) # Output: 5

x se pasa como 10. Pero es inmediatamente sombreado y sobrescrito por x=5

Cada llamada recursiva obtiene su propio contexto de ejecuciónlo que significa que las variables y parámetros locales en esa llamada son independientes de las llamadas anteriores.

Sin embargo, si una variable se modifica globalmente o se transmite explícitamente como parámetro, el cambio puede influir en llamadas recursivas posteriores.

  • variables locales: Estos se definen dentro de la función y solo afectan el actual nivel de recursividad. No persisten entre llamadas.
  • Parámetros pasados ​​explícitamente a la siguiente llamada recursiva conservan sus valores de la llamada anterior, lo que permite que la recursividad acumule estado en todos los niveles.
  • variables globales: Estos son compartido en todos los niveles de recursividad. Si se modifica, el cambio será visible para todos los niveles de recursividad.

Ilustremos esto con un ejemplo.

Ejemplo 1: uso de una variable global (no recomendado)

counter = 0  # Global variable

def count_up(n):
global counter
if n > 0:
counter += 1
count_up(n - 1)

count_up(5)
print(counter) # Output: 5

counter es una variable global compartida entre todas las llamadas recursivas. Se incrementa en cada nivel de recursividad y su valor final (5) se imprime una vez que se completa la recursividad.

Ejemplo 2: uso de parámetros (recomendado)

def count_up(n, counter=0):
if n > 0:
counter += 1
return count_up(n - 1, counter)
return counter

result = count_up(5)
print(result) # Output: 5

  • counter es ahora un parámetro de la función.
  • counter se pasa de un nivel de recursividad al siguiente, con su valor actualizado en cada nivel. El counter no se reinicializa en cada llamada, sino que se El estado actual se pasa al siguiente nivel de recursividad..
  • La función ahora es puro — no tiene efectos secundarios y sólo actúa dentro de su propio alcance.
  • Cuando la función recursiva regresa, el counter “sube” al nivel superior y regresa al caso base.

1. Utilice nombres de variables descriptivos

Evite nombres vagos como df o x. Utilice nombres descriptivos como customer_sales_df o sales_records_df para mayor claridad.

2. uso capital letters para constantes

Esta es la convención de nomenclatura estándar para constantes en Python. Por ejemplo, MAX_RETRIES = 5.

3. Evite las variables globales tanto como sea posible

Las variables globales introducen errores y hacen que el código sea más difícil de probar y mantener. Es mejor pasar variables explícitamente entre funciones.

4. Trate de escribir funciones puras siempre que sea posible.

¿Qué es una función pura?

  1. determinista: Siempre produce la misma salida para la misma entrada. No se ve afectado por estados externos o aleatoriedad.
  2. Sin efectos secundarios: No modifica ninguna variable o estado externo. Opera únicamente dentro de su ámbito local.

Usando nonlocal o global haría la función impura.

Sin embargo, si está trabajando con un cierredeberías usar el nonlocal palabra clave para modificar variables en el ámbito circundante (externo), lo que ayuda a evitar el sombreado de variables.

A cierre ocurre cuando una función anidada (función interna) captura y hace referencia a variables de su función adjunta (función externa). Esto permite que la función interna “recuerde” el entorno en el que se creó, incluido el acceso a las variables desde el alcance de la función externa, incluso después de que la función externa haya terminado de ejecutarse.

El concepto de cierres puede ser muy profundo, ¡así que cuéntame en los comentarios si esto es algo en lo que debería profundizar en el próximo artículo! 🙂

5. Evite el sombreado de variables y el sombreado de parámetros.

Si necesita hacer referencia a una variable externa, evite reutilizar su nombre en un ámbito interno. Utilice nombres distintos para distinguir claramente las variables.

¡Eso es todo! Gracias por quedarte conmigo hasta el final.

¿Ha encontrado alguno de estos desafíos en su propio trabajo? ¡Deja tus pensamientos en los comentarios a continuación!

Escribo regularmente sobre Python, el desarrollo de software y los proyectos que construyo, así que sígueme para no perdértelo. Nos vemos en el próximo artículo 🙂