Decoradores
Last updated
Last updated
Los decoradores son una forma de modificar o extender la funcionalidad de una función en Python. Básicamente, un decorador es una función que toma otra función y la modifica sin cambiar el código fuente original.
Estos se utilizan para agregar funcionalidad a una función existente sin tener que modificar su código fuente original. Esto puede ser útil para agregar características como verificación de entrada, registro de llamadas o temporización a una función sin tener que agregar esta funcionalidad a la función en sí.
Para crear un decorador en Python, simplemente definimos una función que tome otra función como argumento y devuelva una función modificada. Por ejemplo, si queremos crear un decorador que imprima un mensaje antes y después de la ejecución de una función, podemos hacerlo de la siguiente manera:
En este ejemplo, el decorador "decorator" toma una función "func" como argumento. La función "wrapper" se define dentro del decorador y toma cualquier número de argumentos posicionales y de palabras clave. La función "wrapper" ejecuta algún código antes y después de llamar a la función original "func". La función "wrapper" devuelve el resultado de la función original.
Para aplicar este decorador a una función, simplemente coloque el símbolo "@" antes del nombre del decorador sobre la definición de la función:
Esta es la manera habitual en la que se aplica un decorador, sin embargo lo que esta aciendo internamente es asignar la funcion wraper()
devuelta por el decorador decorator()
a nuestra funcion my_function()
. El sigueinte codigo hace los mimso que el mostrado anteriormente:
El wrapper
es una función que se utiliza en la creación de decoradores. Su función principal es envolver la función original, que se quiere decorar, dentro de otra función que agrega alguna funcionalidad adicional sin modificar la función original.
El wrapper
es una función interna que se define dentro de la función decoradora y que tiene acceso a la función original y a los argumentos que se le pasan. Es decir, el wrapper
es la función que se ejecuta antes y después de la función original, y puede hacer cualquier cosa que se necesite antes o después de la llamada a la función original
Por ejemplo, si se tiene el siguiente decorador que agrega una función adicional de impresión antes de la llamada a la función original:
En este caso, wrapper
es la función interna que envuelve a la función original func
. *args
y **kwargs
permiten que el decorador acepte cualquier número de argumentos y parámetros, lo que es útil en caso de que se quiera aplicar el decorador a una función con diferentes números de argumentos y parámetros.
En la última línea del decorador, la función wrapper
se retorna para que se pueda hacer la reasginacion de la funcion de la que se ha hablado anteriormente
Es importante tener en cuenta que los decoradores también pueden recibir argumentos. Para ello, debemos definir una función que devuelva el decorador deseado. Por ejemplo, si queremos un decorador que acepte un argumento entero y añada ese número de saltos de línea después de la ejecución de la función original, podemos definirlo de la siguiente manera:
Para utilizar este decorador con argumentos, simplemente debemos llamar a la función que devuelve el decorador con los argumentos deseados y colocar el resultado encima de la definición de la función que queremos decorar.
En este caso, la función my_function()
será decorada con un salto de línea de tres líneas después de su ejecución.
Un decorador de temporización se puede utilizar para medir el tiempo de ejecución de una función. Por ejemplo, si queremos medir el tiempo que tarda una función en ejecutarse, podemos usar el siguiente decorador:
Para aplicar este decorador a una función, podemos usar la sintaxis @temporizador antes de la definición de la función:
Un decorador de registro de llamadas se puede utilizar para registrar todas las llamadas a una función. Por ejemplo, si queremos registrar todas las llamadas a una función y escribir las llamadas en un archivo de registro, podemos usar el siguiente decorador:
Para aplicar el decorador a una función, simplemente debemos colocar el símbolo @ seguido del nombre del decorador encima de la definición de la función que queremos decorar. Por ejemplo:
En este ejemplo, la función my_function()
será decorada con el decorador my_decorator
. Al llamar a my_function()
, en realidad estaremos llamando a la función devuelta por el decorador, que a su vez llamará a la función original.
Podemos ver que el decorador ha añadido funcionalidad antes y después de la ejecución de la función original.