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

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

Comencemos el 2025 escribiendo código limpio juntos

Imagen de Hinchazón Desde desempaquetar

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

¿La buena noticia? Escribir código limpio y bien extendido no requiere esfuerzo adicional una vez que comprende los conceptos 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 pudiera acceder a todas las variables desde cualquier lugar, tendría que realizar un seguimiento de todas ellas para evitar sobrescribirlas accidentalmente.

En Python, el alcance está definido por el regla LEGBlo que significa: local, abarcadora, global e integrada.

Encuadre en Python, llamado 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. Alcance local

Las variables dentro de una función están en el ámbito local. Sólo son accesibles en esta función.

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

2. Alcance

Estos se refieren a variables en una función que contiene un anidado función. Estas variables no son globales pero son accesibles 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 la palabra clave se utiliza para modificar variables en el ámbito adjunto, no solo los leo.

Por ejemplo, supongamos que desea actualizar la variable total_after_discountque está dentro del alcance de la función. Sin nonlocalsi lo atribuyes a total_after_discount dentro de la función interna, Python lo tratará como una nueva variable local.eficazmente sombreado la variable externa. Esto puede introducir errores y comportamientos inesperados.

3. Alcance global

Variables definidas aparte 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 realizados 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 integrado

Se refiere a palabras clave reservadas que Python usa para sus funciones integradas, como print , def , round etcétera. Esto es accesible a 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 un ámbito cerrado (no global).

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

En el ámbito interno, todas las referencias a la variable apuntarán a la variable interna y no a la variable 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 regresa a la variable de alcance externo.

He aquí un ejemplo rápido. x está oculto en cada ámbito, lo que lleva a 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

Similar en concepto al sombreado de variables, pero esto ocurre cuando una variable local anula o anula un parámetro pasado a una función.

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

foo(10) # Output: 5

x aumentado a 10. Pero se oculta inmediatamente y se sobrescribe por x=5

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

Sin embargo, si una variable se cambia globalmente o se pasa 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 estados en todos los niveles.
  • variables globales: Estos son compartido en todos los niveles de recursividad. Si se modifica, el cambio será visible en 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 ahora es un configuración 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 reinicia en cada llamada, sino que El estado actual pasa al siguiente nivel de recursividad..
  • La función ahora es puro — no tiene efectos secundarios y sólo actúa en su propia zona.
  • Cuando la función recursiva regresa, el counter «burbujas» hasta el 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. Intente escribir funciones puras cuando 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 ni por el azar.
  2. Sin efectos secundarios: No modifica ninguna variable o estado externo. Opera únicamente dentro de su área local.

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

Sin embargo, si trabaja con un cierredebes usar el nonlocal palabra clave para modificar variables en el alcance circundante (externo), lo que ayuda a evitar la observación de variables.

A cierre ocurre cuando una función anidada (función interna) captura y hace referencia a las 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 variables dentro del alcance de la función externa, incluso después de que la función externa haya terminado de ejecutarse.

El concepto de cierre puede ser muy útil, ¡así que déjame saber en los comentarios si esto es algo que debería cubrir en el próximo artículo! 🙂

5. Evite observar variables y observar parámetros.

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

¡Se acabó! 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 creo, así que sígueme para no perdértelo. Nos vemos en el próximo artículo 🙂