Aprovecha el precio especial

Antes:$249

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Comienza ahora

Termina en:

02d

15h

56m

01s

1

Funciones anidadas y como objetos de primera clase

Funciones: base de los decoradores

Antes de empezar a hablar de decoradores, recordemos que una función retorna un valor ante la entrada de un argumento:

defal_cuadrado(numero):return numero ** 2

Esta función recibe el arguemnto numero y a partir de eso retorna (return) el argumento numero elevado al cuadrado (numero ** 2).

Ahora, probemos esta función. Si damos como parámetro el número 4, tendremos como salida el valor número 16 (es el valor que nos retorna):

>>> al_cuadrado(4)
16

Si no sabes o no te queda claro la diferencia entre argumentos y parámetros de las funciones, te invito a que vayas a este Colab (https://colab.research.google.com/drive/1VyOB8nRWRTscc7k_V-66NIlfKZZZ8AuW?usp=sharing) y que vayas hacia las sección Funciones y dentro vayas a la secciones Argumentos y Parámetros de las funciones y Los argumentos NO son lo mismo que los parámetros. Allí explico esta confusión qué suele ocurrir en programación.


Los decoradores son una forma sencilla de llamar funciones de orden mayor, qué básicamente son funciones que toman otra función como parámetro y/o retornan otra función como resultado. Entonces, un decorador le añade capacidades a una función sin tener que modificarla.

Un ejemplo son las llantas de un coche, a las cuáles les puede añadir cadenas para la nieve. No modificas el comportamiento de que aún pueda andar, porqué sí puede, y además extiendes su funcionalidad a otros terrenos.

Funciones como objetos de primera clase

Cómo vimos en el curso anterior, las funciones son objetos de primera clase, lo que significa que puede ser pasados y usados como argumentos al igual que cualquier otro objeto(int, float, str). Veamos un ejemplo dónde utilizamos 3 funciones en conjunto:

defpresentarse(nombre):return f'¡Hola! Me llamo {nombre}.'defaprender(nombre):return f'¡{nombre}, aprendamos Python!'defusar_funciones(funcion):return funcion("Ignacio") #establecemos el parámetro que tomarán las primeras 2 funciones

Las primeras 2 funciones nos retornan strings. Pero la última, se comportará diferente según la función que le pasemos como parámetro. Veamos cómo se puede usar:

>>> print(usar_funciones(presentarse))
¡Hola! Me llamo Ignacio.

>>> print(usar_funciones(aprender))
¡Ignacio, aprendamos Python!

Cómo ves, nos imprime los mensajes que retornaban las 2 primeras funciones con el nombre correspondiente. Fíjate que para referirnos como parámetros a las 2 primeras funciones no ponemos paréntesis, sino que las escribimos así presentarse y aprender. Además, automáticamente reciben como parámetro el nombre "Ignacio", qué es el argumento nombre de las funciones.


Funciones anidadas

Esto también lo vimos en el curso anterior, dónde podíamos meter funciones dentro de otras funciones al igual que las condicionales:

numero = 5if numero > 1:
  if numero % 2 == 0:
    print("Este número es compuestoo.")

  else:
    print("Este número es primo.")

else:
  print("Este número es igual o menor a 1."
>>> (ejecutamos)
Este número es primo

Ahora veamos cómo aplica este concepto para las funciones:

deffuncion_padre(numero):defdoble():
    resultado = numero * 2
    print('El doble de {numero} es {resultado}.')

  defal_cuadrado():
    resultado = numero ** 2
    print('{numero} al cuadrado es {resultado}.')

En esta función (funcion_padre()), la cuál recibe el argumento numero, dentro hay otras 2 funciones (doble y al_cuadrado), las cuales sirven para calcular el doble y/o el cuadrado del argumento recibido, respectivamente. Ahora llamaremos a funcion_padre() para ver qué cosas podemos hacer:

>>> funcion_padre(5)

No se ejecuta nada, y eso es porque debemos agregar a funcion_padre() que las 2 funciones anidadas deben ejecutarse.

deffuncion_padre(numero):defdoble():
    resultado = numero * 2
    print(f'El doble de {numero} es {resultado}.')

  defal_cuadrado():
    resultado = numero ** 2
    print(f'{numero} al cuadrado es {resultado}.')

  doble() #se ejecuta doble() 
  al_cuadrado() #se ejecuta al_cuadrado()>>> funcion_padre(5)
El doble de 5 es 10.5 al cuadrado es 25.

Ahora sí, funcion_padre() funciona, valga la redundancia. Cómo vemos, las funciones doble() y al_cuadrado() no se ejecutan hasta que primero se llama a funcion_padre(). Esto sigue las reglas del scope o alcance. En este caso, no podemos a acceder a las funciones internas sin antes acceder a la función global que contiene dichas funciones internas.

Escribe tu comentario
+ 2