Guía completa del ámbito de variables en Python | Regla LEGB, global y nonlocal explicados a fondo

目次

1. Introducción: ¿Qué es el ámbito de las variables en Python?

Al aprender Python, es posible que te enfrentes al concepto de «ámbito de las variables (Scope)». El ámbito se refiere al rango en el que una variable es accesible, y si no lo entiendes correctamente, puede causar errores inesperados o bugs.

Por ejemplo, veamos el siguiente código.

def my_function():
    x = 10  # Esta variable x solo es válida dentro de la función

print(x)  # NameError: name 'x' is not defined

En este código, se produce un error al intentar referenciar la variable x definida dentro de la función my_function desde fuera de la función. Esto se debe a que x pertenece al «ámbito local», por lo que no existe fuera de la función.

En este artículo, explicaremos en detalle desde los conceptos básicos del ámbito de las variables en Python, hasta usos avanzados y métodos para evitar errores. Aprende a entender correctamente los ámbitos y a gestionarlos de manera adecuada.

2. Conceptos básicos del ámbito de variables

2.1 ¿Qué es el ámbito de variables?

El ámbito de variables se refiere al concepto del rango en el que una variable es válida. En Python, el rango en el que se puede referenciar una variable se determina por dónde se define.

Por ejemplo, una variable definida dentro de una función no se puede acceder desde fuera de esa función. Por el contrario, una variable definida a nivel de módulo se puede utilizar en todo el script.

2.2 ¿Por qué es necesario entender los ámbitos?

Si no se gestiona adecuadamente el ámbito de variables, pueden surgir problemas como los siguientes.

  • Sobreescritura no intencionada de variables
    Si se utilizan variables con el mismo nombre en diferentes ámbitos, puede llevar a errores inesperados.
  • Variable no encontrada (NameError)
    Si se intenta acceder a una variable sin entender su ámbito, NameError puede ocurrir.
  • Disminución de la legibilidad del código
    El uso excesivo de variables de ámbito global hace que las intenciones del código sean poco claras y dificulta la depuración.

2.3 Reglas básicas de los ámbitos en Python

Para entender las reglas de los ámbitos en Python, mantengamos en mente los siguientes puntos.

  1. Las variables definidas dentro de una función son válidas solo dentro de esa función (ámbito local)
  2. Las variables definidas fuera de una función se pueden referenciar en todo el script (ámbito global)
  3. Python tiene una regla de búsqueda de ámbitos llamada «regla LEGB»
  4. Para modificar una variable global dentro de una función, se utiliza la palabra clave global
  5. Para modificar una variable externa en una función anidada, se utiliza la palabra clave nonlocal

De esta manera, en Python, al gestionar adecuadamente los ámbitos, se pueden prevenir errores inesperados y escribir código de manera eficiente.

年収訴求

3. Tipos de ámbitos en Python y ejemplos prácticos

Los ámbitos de variables en Python se dividen principalmente en 4 tipos. Comprender cada ámbito y gestionar las variables de manera adecuada es un punto importante para escribir código sin errores.

  • Ámbito local (Local Scope)
  • Ámbito envolvente (Enclosing Scope)
  • Ámbito global (Global Scope)
  • Ámbito incorporado (Built-in Scope)

En esta sección, explicaremos en detalle cada ámbito con ejemplos concretos.

3.1 Ámbito local (Local Scope)

El ámbito local es el ámbito de las variables definidas dentro de una función. Las variables del ámbito local son válidas solo dentro de esa función y no se pueden acceder desde fuera de la función.

Ejemplo concreto del ámbito local

def my_function():
    x = 10  # x es una variable local de esta función
    print(x)  # Esto funciona sin problemas

my_function()
print(x)  # NameError: name 'x' is not defined

Explicación:
La variable x definida dentro de la función my_function es válida solo mientras se ejecuta la función. Si se intenta acceder a x desde fuera de la función, se produce un NameError.

3.2 Ámbito envolvente (Enclosing Scope)

El ámbito envolvente se refiere al ámbito de la función exterior en funciones anidadas (insertadas). La función interior (función hija) puede acceder a las variables de la función exterior (función padre).

Ejemplo concreto del ámbito envolvente

def outer_function():
    y = 20  # Variable en el ámbito de la función padre

    def inner_function():
        print(y)  # La función hija puede referenciar la variable de la función padre

    inner_function()

outer_function()

Explicación:
Dentro de inner_function, se puede referenciar la variable y de outer_function.

3.3 Ámbito global (Global Scope)

El ámbito global es el ámbito de las variables válidas en todo el script (todo el módulo). Las variables definidas fuera de las funciones se pueden referenciar desde cualquier lugar del script.

Ejemplo concreto del ámbito global

z = 30  # Variable global

def my_function():
    print(z)  # Acceso posible a la variable global

my_function()
print(z)  # Referenciable desde cualquier lugar

3.4 Ámbito incorporado (Built-in Scope)

El ámbito incorporado es el ámbito de las funciones y variables integradas proporcionadas por Python desde el principio. Funciones como print() y len() corresponden a esto.

Ejemplo concreto del ámbito incorporado

print(len([1, 2, 3]))  # Salida: 3

Explicación:
print y len son funciones integradas de Python y se pueden utilizar desde cualquier ámbito.

3.5 Resumen de los 4 ámbitos

Nombre del ámbitoExplicaciónEjemplo
Ámbito localVariable válida solo dentro de la funciónVariable dentro de la función
Ámbito envolventePosible referenciar variables de la función exteriorVariable de función anidada
Ámbito globalVariable referenciable en todo el scriptglobal variable
Ámbito incorporadoFunciones y variables integradas de Pythonprint(), len()

4. Orden de búsqueda del scope de variables (Regla LEGB)

En Python, al referenciar una variable, se busca la variable siguiendo una regla específica. Esta regla se llama regla LEGB (Local, Enclosing, Global, Built-in) y explora las variables en el siguiente orden.

  1. L (Local) Scope local – Variables definidas en la función actual
  2. E (Enclosing) Scope enclosing – Variables de la función exterior (función anidada)
  3. G (Global) Scope global – Variables definidas a nivel de módulo
  4. B (Built-in) Scope built-in – Funciones y variables integradas proporcionadas por Python desde el principio

Al entender esta regla, se puede predecir cómo Python resuelve las variables, lo que facilita evitar errores.

4.1 Ejemplo concreto de la regla LEGB

x = "variable global"  # G (Global)

def outer_function():
    x = "variable enclosing"  # E (Enclosing)

    def inner_function():
        x = "variable local"  # L (Local)
        print(x)  # Por la regla LEGB, se refiere a la x más interna

    inner_function()

outer_function()
print(x)  # Se refiere a la x del scope global

Resultado de la ejecución

variable local
variable global

4.2 Influencia del scope global

Si se intenta modificar una variable global dentro de un scope local, puede ocurrir un UnboundLocalError debido a la influencia de la regla LEGB.

Error al intentar modificar una variable global en local

x = 10  # Variable global

def update_x():
    x += 1  # Ocurre un error
    print(x)

update_x()

Contenido del error

UnboundLocalError: local variable 'x' referenced before assignment

Solución: Usar la palabra clave global

x = 10  # Variable global

def update_x():
    global x  # Especificar explícitamente la variable global
    x += 1
    print(x)

update_x()  # Salida: 11

4.3 Cambio de scope usando nonlocal

Para modificar una variable en el E (Enclosing) scope enclosing de la regla LEGB, se utiliza la palabra clave nonlocal.

Ejemplo concreto de nonlocal

def outer_function():
    count = 0  # Variable de la función exterior

    def inner_function():
        nonlocal count  # Referenciar la variable de la función exterior
        count += 1
        print(count)

    inner_function()
    print(f"Conteo final: {count}")

outer_function()

Resultado de la ejecución

1
Conteo final: 1

4.4 Búsqueda de funciones integradas (Scope Built-in)

Python tiene funciones integradas como print() o len(), que pertenecen al scope más exterior (Built-in).

Ejemplo de sobrescritura de una función integrada

sum = 100  # `sum()` es una función integrada, pero se sobrescribió como variable

print(sum([1, 2, 3]))  # TypeError: 'int' object is not callable

Solución: No sobrescribir funciones integradas

del sum  # Deshacer la sobrescritura
print(sum([1, 2, 3]))  # Funciona normalmente

4.5 Resumen de la regla LEGB

ScopeDescripciónEjemplo
L (Local)Variables definidas dentro de la funcióndef func(): x = 1
E (Enclosing)Variables definidas en la función exteriorFunción anidada
G (Global)Variables definidas a nivel de módulox = 10 (fuera de la función)
B (Built-in)Funciones integradas de Pythonprint(), len()

Al entender la regla LEGB, se puede comprender más profundamente el mecanismo de scopes de variables en Python y prevenir errores.

5. Distinción en el uso de variables globales y locales

En Python, es importante gestionar adecuadamente si colocar las variables en el ámbito global o limitarlas al ámbito local. El abuso de variables globales reduce la legibilidad del código y facilita la aparición de errores.

En esta sección, explicamos en detalle la diferencia entre variables globales y locales y cómo distinguir su uso.

5.1 ¿Qué son las variables globales?

Una variable global (Global Variable) es una variable definida fuera de una función y que puede ser referenciada en todo el script.

Ejemplo concreto de variable global

count = 0  # variable global

def increment():
    global count  # usar variable global
    count += 1

increment()
print(count)  # salida: 1

5.2 ¿Qué son las variables locales?

Una variable local (Local Variable) es una variable definida dentro de una función y que solo es válida en esa función.

Ejemplo concreto de variable local

def my_function():
    x = 10  # variable local
    print(x)

my_function()
print(x)  # NameError: name 'x' is not defined

5.3 Casos en los que se debe usar la palabra clave global

Normalmente, se debe minimizar el uso de variables globales, pero en casos específicos, puede ser apropiado usar la palabra clave global.

Casos apropiados

  • Al gestionar valores de configuración o constantes
  • Cuando sea necesario compartir la misma variable entre múltiples funciones

Ejemplo concreto: Gestión de valores de configuración

MAX_USERS = 100  # variable global (tratar como constante)

def print_max_users():
    print(f"Número máximo de usuarios: {MAX_USERS}")

print_max_users()  # salida: Número máximo de usuarios: 100

5.4 Cómo gestionar variables sin usar global

En lugar de usar variables globales, se puede gestionar los datos de manera más segura aprovechando los argumentos y valores de retorno de las funciones.

Usar argumentos y valores de retorno de funciones

def increment(value):
    return value + 1

counter = 0
counter = increment(counter)  # asignar el valor de retorno de la función
print(counter)  # salida: 1

5.5 Resumen de la distinción en el uso de variables globales y locales

AspectoVariable globalVariable local
Ubicación de definiciónFuera de la funciónDentro de la función
Alcance de accesoReferenciable en todo el scriptSolo dentro de la función definida
Impacto de los cambiosPuede afectar a todas las funcionesEl impacto se limita
VentajasAccesible desde cualquier lugarAlta independencia de la función
DesventajasDifícil de rastrear los cambiosDifícil de usar fuera de la función
Forma de uso recomendadaGestión de constantes o valores de configuraciónUsar variables locales tanto como sea posible

Minimizar el uso de variables globales y aprovechar las locales es la mejor práctica.
Para pasar datos entre funciones, es deseable usar argumentos y valores de retorno de funciones.

6. Funciones anidadas y nonlocal palabra clave

En Python, es posible definir una función dentro de otra función. A esto se le llama funciones anidadas (nested). Al usar adecuadamente las funciones anidadas, se puede organizar la estructura del código y gestionar los ámbitos de manera más fina.

Además, si se desea modificar una variable de la función exterior dentro de una función anidada, es necesario usar la nonlocal palabra clave. En esta sección, se explica en detalle el rol y el uso de nonlocal.

6.1 ¿Qué son las funciones anidadas?

Una función anidada (Nested Function) se refiere a definir una función dentro de otra función.

Ejemplo concreto de una función anidada

def outer_function():
    def inner_function():
        print("Esta es la función interior")

    inner_function()  # Llamar a la función interior dentro de la función exterior

outer_function()  # Salida: Esta es la función interior

6.2 Usar nonlocal para modificar una variable de la función exterior

Normalmente, si se intenta modificar una variable de la función exterior desde la función interior, se produce un error.

Ejemplo en el que ocurre un error

def outer_function():
    count = 0  # Variable de la función exterior

    def inner_function():
        count += 1  # Ocurre un error
        print(count)

    inner_function()

outer_function()

Solución: Usar la palabra clave nonlocal

def outer_function():
    count = 0  # Variable de la función exterior

    def inner_function():
        nonlocal count  # Referenciar la variable de la función exterior
        count += 1
        print(count)

    inner_function()
    print(count)  # El count modificado dentro de `inner_function` se refleja

outer_function()

Resultado de la ejecución

1
1

6.3 Diferencia entre global y nonlocal

Palabra claveÁmbito afectadoUsos específicos
globalVariable global de todo el móduloModificar la variable global desde dentro de una función
nonlocalVariable de la función exterior (ámbito enclosing)Modificar la variable de la función exterior desde una función anidada

Ejemplo usando global

count = 0  # Variable global

def increment():
    global count  # Cambiar la variable global
    count += 1

increment()
print(count)  # Salida: 1

Ejemplo usando nonlocal

def outer():
    count = 0  # Variable del ámbito enclosing

    def inner():
        nonlocal count  # Cambiar la variable de la función exterior
        count += 1

    inner()
    print(count)  # Salida: 1

outer()

global se usa para modificar variables globales desde dentro de una función.
nonlocal se usa para modificar variables exteriores desde una función anidada.

7. Errores comunes relacionados con el ámbito y cómo manejarlos

Si no se comprende adecuadamente el ámbito en Python, pueden surgir problemas como «variable no encontrada», «cambios de valor no intencionados», «errores debido al mal uso del ámbito».

En esta sección, se explican las causas de los errores comunes relacionados con el ámbito y cómo manejarlos.

7.1 UnboundLocalError: Referencia a variable antes de asignación

Ejemplo de ocurrencia del error

count = 0  # Variable global

def increment():
    count += 1  # Error ocurre aquí
    print(count)

increment()

Contenido del error

UnboundLocalError: local variable 'count' referenced before assignment

Solución ①: Usar la palabra clave global

count = 0  # Variable global

def increment():
    global count  # Variable global explícita
    count += 1
    print(count)

increment()  # Salida: 1

Solución ②: Usar argumentos de función

def increment(count):
    return count + 1

count = 0
count = increment(count)
print(count)  # Salida: 1

7.2 NameError: Variable no definida

Ejemplo de ocurrencia del error

def print_message():
    print(message)  # Error ocurre aquí

print_message()

Contenido del error

NameError: name 'message' is not defined

Solución

Definir la variable dentro de la función o recibirla como argumento.

def print_message(message):
    print(message)

print_message("Hola")  # Salida: Hola

7.3 TypeError: Variable con el mismo nombre que una función incorporada

Si se define una variable con el mismo nombre que una función incorporada de Python, puede ocurrir un TypeError al llamar a la función.

Ejemplo de ocurrencia del error

sum = 100  # Variable con el mismo nombre que la función incorporada `sum()`

print(sum([1, 2, 3]))  # Error ocurre aquí

Contenido del error

TypeError: 'int' object is not callable

Solución

  1. Cambiar el nombre de la variable
total = 100  # Usar `total` en lugar de `sum`
print(sum([1, 2, 3]))  # Funciona correctamente
  1. Si se sobrescribió una función incorporada, eliminarla
sum = 100
del sum  # Deshacer la sobrescritura

print(sum([1, 2, 3]))  # Funciona correctamente

7.4 Mejores prácticas para evitar errores relacionados con el ámbito

Usar variables locales siempre que sea posible (limitando el ámbito para prevenir cambios inesperados)
No modificar variables globales dentro de funciones (evitar global en lo posible y manejar con argumentos y valores de retorno)
Verificar que no se usen variables con el mismo nombre que funciones incorporadas
Considerar el ámbito de las variables y seleccionar el ámbito adecuado

8. Consejos para gestionar adecuadamente el ámbito

Gestionar adecuadamente el ámbito en Python es extremadamente importante para mejorar la legibilidad del código y prevenir errores. En particular, el abuso de variables globales o una gestión inadecuada del ámbito puede causar comportamientos inesperados y dificultades en la depuración.

En esta sección, se presentan consejos prácticos para gestionar el ámbito de manera adecuada.

8.1 Reducir al mínimo las variables globales

Las variables globales son accesibles desde cualquier lugar, por lo que es fácil que se produzcan cambios de valores no intencionados. Por eso, se recomienda minimizar el uso de variables globales.

Mal ejemplo (abuso de variables globales)

counter = 0  # Variable global

def increment():
    global counter  # Modificar la variable global
    counter += 1

increment()
print(counter)  # Salida: 1

Buen ejemplo (aprovechar argumentos y valores de retorno de funciones)

def increment(value):
    return value + 1

counter = 0
counter = increment(counter)
print(counter)  # Salida: 1

8.2 Definir claramente el ámbito de las funciones

Si se gestiona adecuadamente el ámbito de las funciones, se puede limitar el rango de influencia de las variables y prevenir cambios no intencionados.

Buen ejemplo (aprovechar el ámbito local)

def calculate_square(number):
    result = number ** 2  # Variable local
    return result

print(calculate_square(4))  # Salida: 16

8.3 Uso adecuado de global y nonlocal

Casos en los que se debe usar global

  • Al gestionar valores de configuración o constantes
  • Variables para mantener el estado (ej.: patrón singleton)
MAX_USERS = 100  # Variable global (tratar como constante)

def get_max_users():
    return MAX_USERS

print(get_max_users())  # Salida: 100

Casos en los que se debe usar nonlocal

  • Al modificar una variable externa en una función anidada
def outer():
    count = 0  # Variable de la función externa

    def inner():
        nonlocal count  # Modificar la variable externa
        count += 1
        print(count)

    inner()

outer()  # Salida: 1

8.4 Lista de verificación para la gestión del ámbito

¿Las variables que se completan dentro de una función utilizan variables locales en lugar de globales?
¿En el caso de usar variables globales, es realmente un caso necesario? (valores de configuración o constantes, etc.)
¿Al pasar datos entre funciones, se utilizan argumentos y valores de retorno en lugar de variables globales?
¿El uso de global o nonlocal es adecuado? (¿no se usa de manera innecesaria?)
¿No se utilizan variables con el mismo nombre que funciones integradas?
¿Se diseña el código considerando el ámbito de las variables?

Al utilizar esta lista de verificación, se pueden prevenir problemas de ámbito de antemano y escribir código más seguro y fácil de mantener.

9. FAQ (Preguntas frecuentes y respuestas)

En esta sección, hemos recopilado las preguntas frecuentes sobre el alcance de variables en Python.
Para disipar malentendidos sobre los alcances y profundizar en una comprensión más práctica, lo explicamos en formato de preguntas y respuestas.

9.1 global ¿Cómo gestionar variables globales sin usar?

A: Al usar argumentos de función y valores de retorno, se puede evitar modificar las variables globales.

def increment(value):
    return value + 1

count = 10
count = increment(count)
print(count)  # Salida: 11

Al usar este método, las funciones son independientes y se mejora su reutilización.

9.2 ¿Cuál es la diferencia entre nonlocal y global?

A: nonlocal se usa para modificar variables del ámbito enclosing.

Palabra claveÁmbito afectadoUsos específicos
globalVariable globalModificar variables a nivel de módulo
nonlocalVariables de la función exterior (ámbito enclosing)Modificar variables de funciones anidadas

Ejemplo de uso de nonlocal

def outer():
    count = 0  # Variable de la función exterior

    def inner():
        nonlocal count  # Modificar la variable exterior
        count += 1

    inner()
    print(count)  # Salida: 1

outer()

9.3 ¿Qué es la regla LEGB?

A: Es una regla que indica el orden de búsqueda de variables.

  1. L (Local): Variables definidas dentro de la función
  2. E (Enclosing): Variables fuera de las funciones anidadas
  3. G (Global): Variables del ámbito global
  4. B (Built-in): Funciones integradas de Python

Ejemplo de la regla LEGB

x = "variable global"  # G

def outer():
    x = "variable enclosing"  # E

    def inner():
        x = "variable local"  # L
        print(x)  # Según la regla LEGB, se refiere a la x más interna

    inner()

outer()
print(x)  # Referencia a la variable global

Al entender la regla LEGB, se comprende el mecanismo de los alcances de variables en Python.

10. Resumen

En este artículo, hemos explicado en detalle el alcance de variables en Python. Al entender y gestionar adecuadamente los alcances, es posible prevenir errores y escribir código de alta legibilidad.

10.1 Conceptos básicos de los alcances en Python

¿Qué es un alcance?

  • Es la regla que determina el rango en el que una variable es accesible.
  • Alcance local (dentro de funciones) y alcance global (fuera de funciones) son los básicos.

¿Por qué es necesario entender los alcances?

  • Previene la sobrescritura no intencional de variables.
  • Evita errores como el de variable no encontrada (NameError, etc.).
  • Mejora la legibilidad del código y facilita la depuración.

10.2 Tipos de alcances en Python

Python tiene 4 tipos de alcances y las variables se buscan según la regla LEGB.

AlcanceDescripciónEjemplo
L (Local)Variable definida dentro de una funcióndef func(): x = 1
E (Enclosing)Variable definida en una función exteriorFunción anidada
G (Global)Variable referenciable en todo el scriptx = 10 (fuera de funciones)
B (Built-in)Funciones y variables integradas de Pythonprint(), len()

10.3 Uso correcto de global y nonlocal

Casos en los que usar global

  • Al gestionar constantes o valores de configuración
  • Al usar una variable común en múltiples funciones

Casos en los que usar nonlocal

  • Al querer modificar una variable exterior en una función anidada

10.4 Mejores prácticas para la gestión de alcances

Minimiza el uso de variables globales y prioriza las variables locales.
Para compartir datos entre funciones, usa argumentos y valores de retorno como mejor práctica.
Entiende las reglas de alcances (LEGB) y ten en cuenta el orden de búsqueda de variables.

10.5 En resumen

La comprensión y gestión correcta de los alcances es esencial para mejorar las habilidades en programación con Python. En particular, al prestar atención a «no abusar de las variables globales» y «hacer explícito el alcance de las funciones», podrás escribir un código mejor.

¡Domina los alcances en Python y aspira a escribir código más seguro y fácil de mantener! 🚀