Hola, mi nombre es Antonio
Alfonso Martínez y en el presente articulo nos proponemos a dar unas
breves pinceladas acerca del uso de decoradores en python.
Para empezar diremos que los
“decoradores” son funciones, las cuales, toman como argumento otra
función como argumento para acabar generando una tercera función (la
cual incorporará las funciones de la función decorada). Se trata de un
método que nos permitirá ampliar las funcionalidades de una función
definida, en determinadas circunstancias. Lo dicho también podría
aplicarse a las clases, aunque a la aplicación de decoradores a clases,
dedicaremos otro artículo en el futuro.
En nuestra explicación partiremos de una
sencilla función (a la que llamaremos “hola”) cuyo único cometido será
mostrar en pantalla el mensaje “¡HOLA!”:
Como se puede apreciar, hemos creado una
función muy sencilla. Acto seguido, vamos a “decorar” nuestra función,
haciendo uso de otra función, decoradora a la que daremos el nombre de
“decoraror”:
Así hemos creado nuestro decorador, el
cual tomará como argumento (“funci”) la función a decorar (que en
nuestro ejemplo es la ya referida “hola()”) para retornar una nueva
función (llamada “saludo”) que definimos dentro del decorador y que, a
la ejecución de la función original (“hola”), añadirá un texto antes y
después de la ejecución de la función a decorar.
Una vez creado nuestro decorador, lo que
haremos será aplicarlo a la función que queremos decorar (función “hola”
en nuestro ejemplo). Para ello lo que haremos será introducir el
símbolo “@” seguido del nombre de la función que vamos a emplear como
decorador (a la que dimos el nombre de “decorador” en nuestro ejemplo)
para, en las líneas siguientes, definir la función que queremos decorar,
tal y como se puede apreciar en la imagen siguiente:
Así, el empleo de “@” seguido del nombre del decorador aplicado sobre la función “hola” vendría a equivaler a “hola=decorador(hola)”.
Con ello nuestra función “decorador”
tomará como argumento la función “hola” para retornar la función
“saludo” la cual añadirá los textos “Python te saluda” y “Tenga un buen
día” antes y después de la ejecución de la función “hola”:
Así, tal y como se aprecia en la imagen,
hemos “decorado” nuestra función original para que incorpore un texto
antes y después de la visualización del saludo original.
Hasta ahora hemos procedido a la
“decoración” de una función sin argumentos. De modo que si quisiéramos
aplicar el decorador que hemos creado a una función con argumentos, tal
acción no podría llevarse a cabo (dando lugar a un error).
Es por ello que lo que vamos a hacer a
continuación es modificar nuestro decorador de tal forma que pueda
aplicarse sobre funciones que reciban argumentos. Para este nuevo
ejemplo partiremos de una nueva función a decorar que llevará el nombre
de “división”:
Acto seguido vamos a crear el
correspondiente decorador de modo que pueda recibir como argumento
nuestra función “division”. Para ello escribiremos lo siguiente:
Como se puede apreciar, hemos dado a
nuestro decorador una estructura muy similar a la que veíamos para el
caso anterior, con la salvedad que la función que va a retornar
(“div_text” en este caso) recibe como argumentos, los propios de la
función original, introduciendo por convención “*args” y “**kwargs” para
poder introducir en la nueva función los argumentos y variables que
deseemos introducir. A su vez, crearemos la variable “resultado” que
será igual a la aplicación de la función “division” sobre los valores
que definiremos más adelante (dicha aplicación se producirá en la
ejecución de la nueva función “div_text” que es la que finalmente
retornará nuestro decorador).
Una vez creado el decorador, lo aplicamos
(tal y como veíamos con anterioridad) sobre la función decorada
(función “division” en este caso) la cual recibe como argumentos las
variables “num” y “num2”, tal y como se aprecia en la imagen de arriba.
Acto seguido visualizaremos el resultado dando a las variables “num” y
“num2” los valores 12 y 7 respectivamente:
Ejecutamos el programa y obtenemos el siguiente resultado:
Como se aprecia, junto al “imput”
original de nuestra función decorada “division” (consistente en la
división de los valores introducidos para “num” y “num2”) se han añadido
los textos aportados por la nueva función retornada por el decorador.
Pero además de la visualización de
textos, podemos añadir a nuestra función originaria más y distintas
funcionalidades, así, por ejemplo si quisiéramos que en un determinado
caso, se mostrara, junto al resultado de la división, el tiempo en
segundos que ha tardado en efectuarse:
Como se ve, para este caso, hemos hecho
uso del módulo “time”, para luego, mediante las variables “t1” y “t2”
efectuar el cálculo del tiempo, en segundos, empleado en la ejecución de
la función, obteniendo el siguiente resultado:
De ese modo hemos logrado añadir a la función original, la funcionalidad de mostrar el tiempo en segundos (cuyo valor es, naturalmente 0.0).
Este último ejemplo lo podeis ver en el siguiente enlace a Github:
https://github.com/antonioam82/ejercicios-python/blob/master/funci.py
Saludos.
This is a really informative knowledge, Thanks for posting this informative Information. Cloud Computing
ResponderBorrar