Acordeón de los Índices
Índice de los temas
Python Scope
🌐 Python Scope: La Visibilidad de las Variables
El **scope** en Python determina la visibilidad de los nombres (variables, funciones, clases, etc.) dentro de un programa. Define las regiones del código desde donde se puede acceder a un nombre en particular. Python sigue un conjunto de reglas para determinar el scope de una variable.
La comprensión del scope es fundamental para:
- Evitar conflictos de nombres: Permite usar el mismo nombre de variable en diferentes partes del programa sin que interfieran entre sí.
- Organizar el código: Ayuda a encapsular variables dentro de ciertas secciones del código, haciéndolo más modular y legible.
- Gestionar la vida útil de las variables: Las variables tienen un ciclo de vida limitado por su scope.
Reglas del Scope en Python: El Acrónimo LEGB
Python utiliza la regla **LEGB** para determinar el scope de un nombre cuando se hace referencia a él:
- Local (L): El scope de los nombres definidos dentro de una función. Estos nombres solo son accesibles desde el interior de la función donde se definieron.
- Enclosing function locals (E): El scope de los nombres en las funciones envolventes (para funciones anidadas). Si un nombre no se encuentra en el scope local, Python busca en los scopes locales de todas las funciones envolventes, de adentro hacia afuera.
- Global (G): El scope de los nombres definidos en el nivel superior del módulo o archivo del programa. Las variables globales son accesibles desde cualquier parte del programa.
- Built-in (B): El scope de los nombres predefinidos en el lenguaje
Python (funciones como
print()
,len()
, excepciones comoTypeError
, etc.). Estos nombres siempre están disponibles.
Python busca un nombre en estos scopes en el orden LEGB. El primer lugar donde se encuentra el nombre es el scope que se utiliza.
Ejemplo Ilustrativo:
# Scope Global
variable_global = 10
def funcion_externa():
# Scope de la función envolvente (Enclosing)
variable_envolvente = 20
def funcion_interna():
# Scope Local
variable_local = 30
print(variable_local) # Accede a la variable local (L)
print(variable_envolvente) # Accede a la variable de la función envolvente (E)
print(variable_global) # Accede a la variable global (G)
print(len("Hola")) # Accede a la función built-in (B)
funcion_interna()
funcion_externa()
print(variable_global) # Accede a la variable global (G)
try:
print(variable_local) # Generará un NameError: variable_local no está definida en el scope global
except NameError as e:
print(f"Error: {e}")
try:
print(variable_envolvente) # Generará un NameError: variable_envolvente no está definida en el scope global
except NameError as e:
print(f"Error: {e}")
En los siguientes temas, exploraremos en detalle los scopes local y global, así como las
palabras clave global
y nonlocal
.
Local Scope
📍 Local Scope: Dentro de las Funciones
El **scope local** se refiere al ámbito de las variables que se definen dentro del cuerpo de una función. Estas variables son creadas cuando se llama a la función y dejan de existir cuando la función termina su ejecución. Por lo tanto, solo son accesibles desde el interior de la función en la que fueron definidas.
Características del Scope Local:
- Creación y Destrucción: Las variables locales se crean al invocar la función y se destruyen al finalizar la función.
- Accesibilidad Limitada: Solo el código dentro de la función puede acceder directamente a sus variables locales. No se puede acceder a ellas desde fuera de la función.
- Nombres Independientes: Se pueden tener variables locales con el mismo nombre en diferentes funciones, ya que cada una existe en su propio scope local y son independientes entre sí.
Ejemplo Ilustrativo:
def mi_funcion():
variable_local = "Soy local a mi_funcion"
print(variable_local)
mi_funcion() # Output: Soy local a mi_funcion
try:
print(variable_local) # Generará un NameError porque variable_local no está definida en el scope global
except NameError as e:
print(f"Error: {e}")
def otra_funcion():
otra_variable_local = 100
print(otra_variable_local)
otra_funcion() # Output: 100
try:
print(otra_variable_local) # Generará un NameError porque otra_variable_local no está definida en el scope global
except NameError as e:
print(f"Error: {e}")
En este ejemplo, variable_local
solo existe dentro de
mi_funcion()
, y otra_variable_local
solo existe dentro de
otra_funcion()
. Intentar acceder a ellas fuera de sus respectivas funciones
resulta en un NameError
.
Variables Locales y Argumentos de Función:
Los parámetros que se definen en la firma de una función también se consideran variables locales dentro del cuerpo de esa función.
def saludar(nombre):
mensaje = f"Hola, {nombre}!"
print(mensaje)
saludar("Juan") # Output: Hola, Juan!
try:
print(nombre) # Generará un NameError
except NameError as e:
print(f"Error: {e}")
try:
print(mensaje) # Generará un NameError
except NameError as e:
print(f"Error: {e}")
Aquí, tanto el parámetro nombre
como la variable mensaje
son
locales a la función saludar()
.
En el siguiente tema, exploraremos el **scope global** en Python.
Global Scope
🌍 Global Scope: En la Cima del Programa
El **scope global** se refiere al ámbito de las variables que se definen fuera de cualquier función o bloque de código. Estas variables se crean cuando se inicia el programa y persisten hasta que el programa finaliza. En general, son accesibles desde cualquier parte del código, tanto dentro como fuera de las funciones.
Características del Scope Global:
- Definición en el Nivel Superior: Las variables globales se definen en el nivel más alto del archivo del programa (o módulo).
- Accesibilidad General: Se puede acceder a las variables globales desde cualquier función o parte del código.
- Persistencia: Las variables globales existen durante toda la ejecución del programa.
Ejemplo Ilustrativo:
mensaje_global = "Soy una variable global"
def mostrar_mensaje():
print(mensaje_global) # Accede a la variable global
mostrar_mensaje() # Output: Soy una variable global
print(mensaje_global) # Output: Soy una variable global
contador = 0
def incrementar_contador():
global contador # Necesitamos usar 'global' para modificar la variable global
contador += 1
print(f"Contador ahora es: {contador}")
incrementar_contador() # Output: Contador ahora es: 1
incrementar_contador() # Output: Contador ahora es: 2
print(f"Valor global de contador: {contador}") # Output: Valor global de contador: 2
En este ejemplo, mensaje_global
y contador
son variables
definidas en el scope global. La función mostrar_mensaje()
puede acceder a
mensaje_global
directamente. Sin embargo, para modificar una variable
global dentro de una función, se necesita utilizar la palabra clave global
(como se muestra en incrementar_contador()
), de lo contrario, Python
trataría contador
dentro de la función como una nueva variable local.
Precauciones con las Variables Globales:
Si bien las variables globales pueden ser convenientes en algunos casos, su uso excesivo puede llevar a un código más difícil de entender y mantener. Pueden hacer que las funciones sean menos independientes y más propensas a efectos secundarios no deseados. En general, se recomienda limitar el uso de variables globales y preferir pasar datos a las funciones como argumentos y devolver resultados.
La Importancia de la Palabra Clave global
:
Como se mencionó en el ejemplo, si intentas asignar un valor a una variable dentro de una
función, Python asumirá que es una nueva variable local, incluso si existe una variable
con el mismo nombre en el scope global. Para modificar una variable global desde dentro
de una función, debes declararla como global
al principio de la función.
En el siguiente tema, hablaremos sobre las convenciones para nombrar variables en relación con su scope.
Naming Variables
🏷️ Nombrando Variables: Claridad y Convención
Elegir buenos nombres para las variables es una parte crucial de la programación. Los nombres de las variables deben ser lo suficientemente descriptivos para que cualquier persona (incluido tú mismo en el futuro) pueda entender fácilmente el propósito de la variable. En relación con el scope, aunque Python permite usar el mismo nombre para variables en diferentes scopes (local y global, por ejemplo), es importante hacerlo con cuidado para evitar confusiones.
Convenciones Generales para Nombres de Variables en Python:
- Ser Descriptivo: El nombre debe indicar claramente qué almacena la
variable. Por ejemplo,
nombre_usuario
es mejor quen
. - Usar Snake Case: Para nombres de variables con múltiples palabras,
se recomienda usar snake case, donde las palabras se separan por guiones bajos (ej.
cantidad_total
,indice_actual
). - Evitar Palabras Reservadas: No uses palabras reservadas de Python
(como
if
,for
,while
,def
,class
, etc.) como nombres de variables. - Ser Consistente: Mantén un estilo de nombrado coherente en todo tu proyecto.
- Nombres Cortos para Scopes Pequeños: En scopes locales muy pequeños
(como contadores en un bucle corto), nombres cortos como
i
oj
pueden ser aceptables.
Nombres y Scope: Evitando Confusiones
Aunque es técnicamente posible tener una variable global y una variable local con el mismo nombre, generalmente se desaconseja porque puede hacer que el código sea más difícil de leer y entender. Cuando Python encuentra un nombre dentro de una función, primero busca en el scope local. Si encuentra una variable con ese nombre, la utiliza, incluso si hay una variable global con el mismo nombre.
Ejemplo de Sombreamiento de Variables (Variable Shadowing):
variable_compartida = "Soy global"
def mi_funcion():
variable_compartida = "Soy local" # Esta variable local "sombra" a la global
print(variable_compartida) # Output: Soy local
mi_funcion()
print(variable_compartida) # Output: Soy global
En este caso, dentro de mi_funcion()
, variable_compartida
se
refiere a la variable local definida dentro de la función. La variable global con el
mismo nombre queda "sombreada" y no se accede a ella dentro de la función (a menos que
se use la palabra clave global
).
Recomendaciones:
- Usar Nombres Distintos: Siempre que sea posible, utiliza nombres diferentes para las variables en diferentes scopes para evitar el sombreamiento y la confusión.
- Claridad sobre Intención: Si necesitas acceder o modificar una
variable global dentro de una función, utiliza explícitamente la palabra clave
global
para que la intención quede clara. - Considerar el Contexto: Elige nombres que tengan sentido dentro del
contexto de su scope. Una variable llamada
contador
podría ser perfectamente aceptable dentro de una función, pero un nombre más descriptivo podría ser necesario a nivel global.
En los siguientes temas, exploraremos en detalle las palabras clave global
y
nonlocal
, que nos permiten interactuar con variables en scopes diferentes
al local.
Global Keyword
🔑 La Palabra Clave global
: Accediendo al Ámbito
Superior
La palabra clave global
se utiliza dentro de una función para indicar que
una variable a la que se hace referencia debe ser buscada en el scope global. Esto es
especialmente importante cuando se desea modificar el valor de una variable global desde
el interior de una función. Sin la palabra clave global
, cualquier
asignación a una variable dentro de una función crearía una nueva variable local con ese
nombre, incluso si ya existe una variable global con el mismo nombre (como vimos en el
ejemplo de sombreamiento).
Cuándo Usar global
:
- Modificar una Variable Global: Si necesitas cambiar el valor de una
variable que fue definida fuera de la función (en el scope global), debes declararla
como
global
dentro de la función antes de realizar la asignación. - Acceder a una Variable Global (Opcional pero Recomendado para
Claridad): Aunque puedes acceder al valor de una variable global dentro
de una función sin usar
global
(Python buscará en el scope global si no la encuentra localmente), usarglobal
al principio de la función puede hacer que tu intención sea más explícita y el código más legible.
Ejemplo de Modificación de una Variable Global:
contador_global = 0
def incrementar():
global contador_global
contador_global += 1
incrementar()
incrementar()
print(f"El valor de contador_global es: {contador_global}") # Output: El valor de contador_global es: 2
En este ejemplo, al declarar contador_global
como global
dentro
de la función incrementar()
, las operaciones
contador_global += 1
modifican directamente la variable
contador_global
definida en el scope global.
Creación de una Variable Global Dentro de una Función (Generalmente Desaconsejado):
También es posible crear una variable global dentro de una función utilizando la palabra
clave global
. Si el nombre de la variable no existe en el scope global al
momento de la declaración global
dentro de la función, se creará una nueva
variable global.
def crear_variable_global():
global nueva_variable_global
nueva_variable_global = "Soy una variable global creada dentro de una función"
crear_variable_global()
print(nueva_variable_global) # Output: Soy una variable global creada dentro de una función
Si bien esto es posible, generalmente se considera una práctica menos clara y puede dificultar el seguimiento de dónde se definen las variables globales. Es preferible definir las variables globales en el nivel superior del módulo.
Precauciones al Usar global
:
El uso excesivo de la palabra clave global
puede hacer que el código sea más
difícil de entender y mantener, ya que las funciones se vuelven dependientes de
variables definidas fuera de su scope. Esto puede reducir la modularidad y aumentar el
riesgo de efectos secundarios no deseados. En muchos casos, es mejor pasar datos a las
funciones como argumentos y devolver resultados para mantener las funciones más
independientes y predecibles.
En el siguiente tema, exploraremos la palabra clave nonlocal
, que se utiliza
en el contexto de funciones anidadas.
Nonlocal Keyword
🗝️ La Palabra Clave nonlocal
: Accediendo al Scope
Envolvente
La palabra clave nonlocal
se utiliza dentro de una función anidada para
indicar que una variable a la que se hace referencia no es local a la función anidada ni
global, sino que pertenece al scope de una de las funciones envolventes más cercanas.
Cuándo Usar nonlocal
:
- Modificar Variables de Funciones Envolventes: Cuando una función
anidada necesita modificar una variable que está definida en el scope de su función
padre (o una función abuela, etc.), pero no en su propio scope local ni en el scope
global, se debe declarar esa variable como
nonlocal
dentro de la función anidada antes de realizar la asignación. - Acceder a Variables de Funciones Envolventes (Implícito): Si solo
necesitas leer el valor de una variable de una función envolvente, Python la
encontrará automáticamente gracias a la regla LEGB (en la 'E' de Enclosing). Sin
embargo, si planeas modificarla, necesitas
nonlocal
.
Ejemplo Ilustrativo: Contador en Función Anidada
def funcion_externa():
contador = 0
def funcion_interna():
nonlocal contador
contador += 1
print(f"Contador interno: {contador}")
funcion_interna() # Output: Contador interno: 1
funcion_interna() # Output: Contador interno: 2
print(f"Contador externo: {contador}") # Output: Contador externo: 2
funcion_externa()
En este ejemplo:
- La variable
contador
se define en el scope defuncion_externa()
. - Dentro de
funcion_interna()
, la declaraciónnonlocal contador
permite que las operaciones sobrecontador
modifiquen la variable en el scope defuncion_externa()
. - Sin
nonlocal
,contador += 1
dentro defuncion_interna()
habría creado una nueva variable local llamadacontador
que no afectaría a la variable en la función externa.
Diferencia entre global
y nonlocal
:
global
se utiliza para acceder o modificar variables en el scope global (el nivel superior del módulo).nonlocal
se utiliza para acceder o modificar variables en el scope de una función envolvente más cercana (no local ni global).
Restricciones de nonlocal
:
nonlocal
solo puede referirse a variables que ya han sido definidas en el scope de una función envolvente. No se puede usar para crear nuevas variables en el scope envolvente.- Si la variable no se encuentra en ningún scope envolvente, se generará un error.
Ejemplo de Error si nonlocal
no encuentra la variable:
def funcion_externa():
def funcion_interna():
nonlocal mensaje # 'mensaje' no está definido en el scope de funcion_externa
mensaje = "Hola desde la interna"
print(mensaje)
funcion_interna() # Generará un SyntaxError o un NameError dependiendo de la versión de Python
La palabra clave nonlocal
es una herramienta poderosa para trabajar con
funciones anidadas y mantener el estado entre la función envolvente y la función
interna.
0 Comentarios
Si desea contactar comigo, lo puede hacer atravez deste formulario gracias