Decoradores en Python



Importante: Los ejemplos que voy a mostrar sobre decoradores están hechos con la versión de Python 3.8.

¿Que son decoradores?


Son funciones que reciben como argumento otra funcion y devuelve una función. 
Esto lo que hace es sobreescribir el comportamiento de la función que pasamos como argumento.


     

La función A recibe una función B. La función A puede tener una o n cantidades de definiciones de funciones, en otras palabras estas definiciones es lo que modifica el cuerpo o (el prototipo) de la función B. La función C hace algo y retorna algo, a su vez, la función A retorna lo que retorno la función C y podemos ver ese retorno llamando a la función B qué es la que originó todo el desencadenamiento de funciones.
La función C debe tener la misma cantidad de parámetros que la función B.
Hay 2 tipos de de decoradores:

  1. Sin parámetros.

  2. Con parámetros.

Decoradores sin parámetros

Vamos a aplicar la teoría y vamos a crear el ejemplo de arriba.
 
La funcionB está marcada con @funcionA (el decorador). Cuando funcionB se llama, funcionC toma los argumentos de funcionB y lo concatena con una cadena. 
La función B no tiene nada en el cuerpo. ¿Puede tener algo? Si. Vamos hacer que funcionC retorne lo que tenga funcionB más una cadena.
Lo que hicimos fue, en la funcionB poner  el mensaje que tenia la funcionC y en la funcionC llamamos a la funcionB (a todo esto esta función ya tiene el argumento) concatenamos el ¿como estas? y retornamos todo el mensaje.


Decoradores con parámetros

Supongamos que vos quieras tener diferentes opciones y que el cuerpo del decorador cambie de acuerdo al parámetro que has pasado al decorador. Para ello, tenemos que colocar nuestro decorador dentro de otra función. Esa función va a llamar a nuestro decorador y es esa función la que va a recibir el parámetro que después nuestro decorador va a utilizar para bifurcar entre varias opciones.
Para poner en práctica lo antes explicado voy a utilizar la siempre y confiable calculadora.
Voy hacer lo siguiente:

  1. La función calculadora va un argumento llamado option y va a contener a mi decorador operations.

  2. El decorador va a evaluar el parámetro option y en base a eso va a definir una función y retorna un resultado.


Encadenamiento de decoradores

El encadenamiento de decoradores se rige por la proximidad, osea el decorador que este más cerca de la función es el que más prioridad tiene, el orden en el que colocas tus decoradores es muy importante.
Ahora a nuestro ejemplo de la calculadora le está faltando algo, y es que no verificamos si los datos ingresados son valores numéricos.
Para solucionar esto lo haremos mediante un decorador el cual agregaremos a nuestra función operation. 
Este decorador se va a llamar verifications, dentro de este va estar definido la función numbers.
Numbers va a verificar si los argumentos pasados a operation son valores numéricos (aunque se ingrese como cadena) si no lo son retorna False  si lo son retorna True. Este valor será utilizado por la s funciones de nuestro decorador las cuales sí operation retorna True devolverá el cálculo y si no devolverá un mensaje.
Además debemos parsear nuestros datos dentro de las funciones porque nuestro decorador solo retorna un valor booleano, no modifica los argumentos pasados a la función operation
.



Y nuestra función operation quedaría

Como se puede ver primero se ejecuta verification y después se efectúa los cálculos.
NOTA: He agregado otras funciones y llamado a nuestros decoradores para no tener que estar cambiando de signo cada vez que quiera hacer una operación.
El resultado de ejecutar varias veces el mismo código



Como podemos ver el último valor contiene el carácter 'f' por lo que verification devolverá false y eso dentro de cualquiera de las operaciones retorna el mensaje que sale en la pantalla.
Los decoradores son muy utilizados en Django. Como vimos, pueden hacer muy flexible tu código ya que va sobreescribiendo el cuerpo de una función, pero deben ser utilizados prudentemente.


Resumen:

  1. Los decoradores son funciones que alteran el comportamiento de otras funciones.

  2. Hay 2 tipos de decoradores: Con argumento y sin argumento.

  3. Para obtener un decorador con argumento debemos colocar nuestro decorador dentro de una función.

  4. Podemos encadenar decoradores. Estos se rigen por la proximidad. El que está más cerca de la función se ejecuta primero.



¡Saludos pro.grammerjrs del mundo!

Comentarios