Cierres Python
Cierres de Python
En este tutorial, aprenderá sobre el cierre de Python, cómo definir un cierre y las razones por las que debería usarlo.
Variable no local en una función anidada
Antes de entrar en lo que es un cierre, primero debemos entender qué es una función anidada y una variable no local.
Una función definida dentro de otra función se llama función anidada. Las funciones anidadas pueden acceder a las variables del ámbito adjunto.
En Python, estas variables no locales son de solo lectura por defecto y debemos declararlas explícitamente como no locales (usando la palabra clave nonlocal) para poder modificarlas.
El siguiente es un ejemplo de una función anidada que accede a una variable no local.
def print_msg(msg):
# This is the outer enclosing function
def printer():
# This is the nested function
print(msg)
printer()
# We execute the function
# Output: Hello
print_msg("Hello")
Salida
Hello
Podemos ver que el printer()
anidado la función pudo acceder al msg no local variable de la función envolvente.
Definiendo una función de cierre
En el ejemplo anterior, ¿qué pasaría si la última línea de la función print_msg()
devolvió el printer()
función en lugar de llamarlo? Esto significa que la función se definió de la siguiente manera:
def print_msg(msg):
# This is the outer enclosing function
def printer():
# This is the nested function
print(msg)
return printer # returns the nested function
# Now let's try calling this function.
# Output: Hello
another = print_msg("Hello")
another()
Salida
Hello
Eso es inusual.
El print_msg()
la función fue llamada con la cadena "Hello"
y la función devuelta estaba ligada al nombre otra . Al llamar another()
, el mensaje aún se recordaba aunque ya habíamos terminado de ejecutar el print_msg()
función.
Esta técnica por la cual algunos datos ("Hello
en este caso) se adjunta al código se llama cierre en Python .
Este valor en el ámbito adjunto se recuerda incluso cuando la variable queda fuera del ámbito o la función misma se elimina del espacio de nombres actual.
Intente ejecutar lo siguiente en el shell de Python para ver el resultado.
>>> del print_msg
>>> another()
Hello
>>> print_msg("Hello")
Traceback (most recent call last):
...
NameError: name 'print_msg' is not defined
Aquí, la función devuelta aún funciona incluso cuando se eliminó la función original.
¿Cuándo tendremos cierres?
Como se ve en el ejemplo anterior, tenemos un cierre en Python cuando una función anidada hace referencia a un valor en su ámbito adjunto.
Los criterios que se deben cumplir para crear un cierre en Python se resumen en los siguientes puntos.
- Debemos tener una función anidada (función dentro de una función).
- La función anidada debe hacer referencia a un valor definido en la función envolvente.
- La función envolvente debe devolver la función anidada.
¿Cuándo usar cierres?
Entonces, ¿para qué sirven los cierres?
Los cierres pueden evitar el uso de valores globales y proporcionan algún tipo de ocultación de datos. También puede proporcionar una solución orientada a objetos al problema.
Cuando hay pocos métodos (un método en la mayoría de los casos) para implementar en una clase, los cierres pueden proporcionar una solución alternativa y más elegante. Pero cuando la cantidad de atributos y métodos aumenta, es mejor implementar una clase.
Aquí hay un ejemplo simple en el que un cierre podría ser más preferible que definir una clase y crear objetos. Pero la preferencia es toda tuya.
def make_multiplier_of(n):
def multiplier(x):
return x * n
return multiplier
# Multiplier of 3
times3 = make_multiplier_of(3)
# Multiplier of 5
times5 = make_multiplier_of(5)
# Output: 27
print(times3(9))
# Output: 15
print(times5(3))
# Output: 30
print(times5(times3(2)))
Salida
27 15 30
Python Decorators también hace un uso extensivo de los cierres.
Como nota final, es bueno señalar que los valores que se encierran en la función de cierre se pueden encontrar.
Todos los objetos de función tienen un __closure__
atributo que devuelve una tupla de objetos de celda si es una función de cierre. Haciendo referencia al ejemplo anterior, sabemos times3
y times5
son funciones de cierre.
>>> make_multiplier_of.__closure__
>>> times3.__closure__
(<cell at 0x0000000002D155B8: int object at 0x000000001E39B6E0>,)
El objeto de celda tiene el atributo cell_contents que almacena el valor cerrado.
>>> times3.__closure__[0].cell_contents
3
>>> times5.__closure__[0].cell_contents
5
python
- Tipos de datos de Python
- Operadores de Python
- Declaración de paso de Python
- Python Anónimo/Función Lambda
- Diccionario de Python
- Generadores de Python
- Decoradores de pitón
- Python String strip() Función con EJEMPLO
- Funciones Python Lambda con EJEMPLOS
- Función Python abs():Ejemplos de valores absolutos
- Función Python round() con EJEMPLOS