Cómo usar funciones anidadas en Python

Cómo usar funciones anidadas en Python
Este artículo cubrirá una guía sobre el uso de funciones anidadas en Python. Las funciones anidadas o las funciones internas se definen dentro de otras funciones de Python. Son útiles en ciertos patrones de programación y casos de uso. Algunos de ellos se explicarán en este artículo. Todas las muestras de código en este artículo se prueban con Python 3.9.5 en Ubuntu 21.04.

Sobre funciones anidadas / internas

Las funciones anidadas, como su nombre indica, son las funciones de Python que se crean dentro de otras funciones de Python. Además de su propio alcance, la función interna tiene acceso a los objetos disponibles en el alcance de la función exterior. La función interna se puede denominar como un solo objeto Python con sus propios datos y variables. Esta función interna está protegida por la función exterior y no puede llamarse ni referirse desde el alcance global. De esta manera, la función interna actúa como una entidad oculta que funciona solo dentro de los límites de la función externa y el alcance global no se da cuenta de ella. Este proceso también se conoce como "encapsulación" en la programación. Aquí hay un ejemplo de una función anidada en Python.

Def Visibile_outer_function (nombre):
Def Hidden_inner_function ()::
Imprimir (nombre)
Hidden_inner_function ()
visibile_outer_function ("John")
Hidden_inner_function ()

La función exterior toma un argumento obligatorio llamado "nombre". La función interna tiene acceso al alcance de la función exterior para que pueda hacer uso de la variable de nombre. Luego se realiza una llamada a la función interna en la función exterior. A continuación, se realiza una llamada a las funciones internas y externas en el alcance global. Después de ejecutar la muestra de código anterior, debe obtener la siguiente salida:

John
Rastreo (llamadas recientes más última):
Archivo "principal.py ", línea 9, en
Hidden_inner_function ()
NameError: el nombre 'Hidden_inner_Function' no está definido

Como puede ver en la salida, la función exterior funciona bien cuando la llama desde el alcance global. Se lanza un error cuando intenta llamar a la función interna, ya que no hay tal cosa disponible en el alcance global.

Casos de uso de funciones internas

Ahora que entiende un poco sobre las funciones anidadas, es posible que se pregunte sobre su utilidad y cuándo usarlas. Uno de los usos más comunes de las funciones internas es para crear funciones auxiliares dentro de la función principal. Las funciones internas también se pueden usar como decoradores y se pueden usar para implementar cierres en su programa. Estos casos de uso se explican a continuación con ejemplos.

Creando una función de ayudante

Las funciones auxiliares son como cualquier otra función de Python, pero se denominan funciones "ayudantes" porque pueden ayudar a organizar mejor el código complejo y pueden reutilizarse en cualquier cantidad de veces para evitar la repetición del código. A continuación se muestra una muestra de código que ilustra una función de ayudante interno.

Def get_ticket_price (nombre):
miembros = ["Tony", "Peter", "Mark"]
Precio = 10
Def get_discounted_price (descuento = 1.0):
devolución (precio * descuento)
Si el nombre en los miembros:
ticket_price = get_discounted_price (descuento = 0.50)
demás:
ticket_price = get_discounted_price ()
Imprimir ("Precio de boleto para" + Name + "IS: $" + STR (ticket_price))
get_ticket_price ("Tony")
get_ticket_price ("John")

La función externa principal de invocación es "get_ticket_price". Toma el nombre de una persona como argumento obligatorio. La función "get_discounted_price" es una función de ayuda interna que toma "descuento" como un argumento opcional. La lista "miembros" contiene nombres de todos los miembros registrados que son elegibles para un descuento. Se calcula un precio con descuento para los miembros llamando a la función interna y suministrando un valor de descuento como argumento. Esta función de ayuda se puede llamar varias veces en función de los requisitos y también puede cambiar la lógica dentro de la función interna. Por lo tanto, las funciones de ayuda interna le permiten simplificar el código y evitar la repetición innecesaria. Después de ejecutar la muestra de código anterior, debe obtener la siguiente salida:

El precio del boleto para Tony es: $ 5.0
El precio del boleto para John es: $ 10.0

Como puede ver en la salida anterior, Tony obtiene un descuento en el precio del boleto como está en la lista de miembros.

Implementación de cierres

Los cierres son casos de funciones internas que son devueltas por funciones externas. Estas funciones internas tienen acceso al alcance de las funciones externas y continúan teniendo acceso al alcance de la función exterior incluso después de que la función exterior ha dejado de ejecutar. Eche un vistazo a la muestra de código a continuación:

Def get_discounted_price (precio):
def descuento_price (descuento):
precio de devolución * Descuento
return stenteded_price
First_Discount = get_discounted_price (10)
Second_discount = get_discounted_price (10)
Imprimir (First_Discount (0.50))
Imprimir (Second_Discount (0.60))

La función exterior "get_discounted_price" devuelve una referencia a la función interna llamada "descuento_price". Observe que en la declaración de retorno, la función se llama sin aparatos ortopédicos. A continuación, se crean dos nuevas instancias llamadas "First_Discount" y "Second_Dicount" llamando a la función exterior y se suministra un valor para el argumento de "precio" a estas llamadas. En este momento, la función exterior ha terminado de ejecutarse, pero su estado se ha guardado en los objetos First_Discount y Second_Discount. Ahora, cuando llame a las instancias First_Discount y Second_Discount con aparatos ortopédicos y argumentos, ya tendrán acceso a una variable llamada Price junto con su valor. El argumento suministrado a estas instancias ahora va a la función interna que luego devuelve un resultado.

Después de ejecutar la muestra de código anterior, debe obtener la siguiente salida:

5.0
6.0

Los cierres generalmente se usan en situaciones en las que su programa requiere preservar el estado de una función.

Creación de funciones de decoración

Las funciones del decorador en Python modifican el comportamiento de una función de Python existente sin cambiarla. Entonces, cuando adjunta un decorador a una función, puede agregar funcionalidad adicional a la función o modificar su comportamiento mientras mantiene intacto su comportamiento original. Un típico decorador de Python se ve así:

@decorador
Def decorado ():
aprobar

Aquí "@Decorator" modificará el comportamiento de la función "decorada". Puede crear funciones decorador utilizando funciones anidadas. Para crear un decorador, definir una función y pasarla a una función exterior como argumento. Luego se llama a esta función pasada dentro de otra función interna donde puede usarla e implementar la lógica. Finalmente, la función exterior devuelve la función interna que contiene el comportamiento modificado. Eche un vistazo a la muestra de código a continuación.

Def get_discounted_price (cantidad):
def descuento_price ()::
precio = cantidad ()
new_price = precio * 0.50
devolver new_price
return stenteded_price

La función exterior "get_discounted_price" se pasa otra función llamada "cantidad" como argumento. La función interna utiliza la función pasada y le agrega un cierto comportamiento. La función exterior luego devuelve una referencia a la función interna que contiene el comportamiento modificado. Después de definir el decorador, puede llamarlo de la siguiente manera:

@get_discounted_price
Def get_price ()::
regresar 10
print (get_price ())

Los decoradores están unidos a funciones cuyo comportamiento está tratando de modificar. Siempre comienzan con el símbolo "@". Al usar el decorador aquí, está pasando la función "get_price" a la función "get_discounted_price" como argumento. Ahora, cuando llame a la función get_price, no obtendrá 10 como salida, sino un número modificado por el decorador get_discounted_price. Después de ejecutar la muestra de código anterior, debe obtener la siguiente salida:

5.0

El uso del decorador que se muestra arriba es equivalente al siguiente código:

Def get_discounted_price (cantidad):
def descuento_price ()::
precio = cantidad ()
new_price = precio * 0.50
devolver new_price
return stenteded_price
Def get_price ()::
regresar 10
FINAL_PRICE = get_discounted_price (get_price)
print (final_price ())

En lugar de usar una sintaxis "@Decorator" como una taquigrafía, simplemente puede crear una nueva instancia de la función exterior y suministrarle otra función como argumento. El resultado final de ambos patrones de codificación es el mismo. Dado que los decoradores mantienen intacta el comportamiento de la función original, son realmente útiles si desea llamarlos caso por caso y al mismo tiempo preserva la implementación de vainilla de una función decorada.

Conclusión

Puede usar funciones anidadas en una variedad de formas de crear funciones internas que agregan funcionalidad y lógica adicionales a la función exterior. Algunos de los casos de uso más comunes para funciones anidadas se han explicado en el artículo. También puede crear sus propias implementaciones de funciones internas, ya que todas las funciones se tratan como objetos de primera clase en Python y pueden ser devueltos o aprobados como argumentos.