Funciones de temporización con decoradores – Python

Todo en Python es un objeto. Las funciones en Python también objetan. Por lo tanto, como cualquier otro objeto, pueden ser referenciados por variables, almacenados en estructuras de datos como diccionario o lista, pasados ​​como argumento a otra función y devueltos como valor desde otra función. En este artículo vamos a ver la función de temporización con decoradores.

Decorador: un decorador se utiliza para potenciar o modificar una función. Un decorador es una función de orden superior que envuelve otra función y la mejora o la cambia. 

Ejemplo :

La mejor forma de explicar en qué consiste codificando nuestro propio decorador. Suponga que desea imprimir * 10 veces antes y después de la salida de alguna función. Sería muy inconveniente usar declaraciones de impresión en cada función una y otra vez. Podemos hacer esto de manera eficiente con la ayuda de un decorador.

Código:

Python3

def my_decorator(func):
    def wrapper_function(*args, **kwargs):
        print("*"*10)
        func(*args,  **kwargs)
        print("*"*10)
    return wrapper_function
  
  
def say_hello():
    print("Hello Geeks!")
  
@my_decorator
def say_bye():
    print("Bye Geeks!")
  
  
say_hello = my_decorator(say_hello)
say_hello()
say_bye()

Producción:

**********
Hello Geeks!
**********
**********
Bye Geeks!
**********

Explicación :

En el ejemplo anterior, my_decoratores una función decoradora, que acepta func, un objeto de función como argumento. Define una función wrapper_function que llama a funcan y también ejecuta el código que contiene. La función my_decorator devuelve esta wrapper_function.

Entonces, ¿qué sucede cuando escribimos @my_decorator antes de definir cualquier función? Considere el ejemplo de la función say_hello anterior que no está decorada por ningún decorador en el momento de la definición. Todavía podemos usar nuestro decorador para decorar su salida llamando a la función my_decorator y pasando el objeto de la función say_hello como parámetro, que devolverá una función wrapper_function con dos declaraciones de impresión, llamando a la función say_hello() en el medio. Si recibimos esta función modificada en el mismo objeto say_hello, cada vez que llamemos a say_hello() obtendremos la salida modificada.

En lugar de escribir esta sintaxis compleja, podemos simplemente escribir @my_decorator antes de definir la función y dejar el resto del trabajo para el intérprete de python como se muestra en el caso de la función say_bye.

Función de temporizador usando Decorator

La función de temporizador es una de las aplicaciones de los decoradores. En el siguiente ejemplo, hemos creado una función timer_func que acepta un objeto de función func. Dentro de la función del temporizador, hemos definido wrap_func que puede recibir cualquier cantidad de argumentos (*args) y cualquier cantidad de argumentos de palabras clave (**kwargs). Hicimos esto para hacer que nuestro timer_func sea más flexible. 

En el cuerpo de wrap_func, registramos la hora actual t1 usando el método de tiempo del módulo de tiempo, luego llamamos a la función func pasando los mismos parámetros (*args, **kwargs) que recibió wrap_func y almacenó el valor devuelto en el resultado. Ahora hemos registrado nuevamente el tiempo actual t2 e impreso la diferencia entre los tiempos registrados, es decir, {t2 – t1} con precisión hasta el 4° lugar decimal. Este {t2 – t1} es el tiempo transcurrido durante la ejecución de la función func. Por fin, devolvimos el valor del resultado dentro de la función wrap_func y devolvimos esta función wrap_func dentro de la función timer_func.

También hemos definido la función long_time usando el decorador @timer_func, por lo que siempre que llamemos a la función long_time se llamará así:

timer_func(long_time)(5)

Cuando se llama a la función timer_func pasando long_time como parámetro, devuelve una función wrap_func y un objeto de función func comienza a apuntar a la función long_time.

wrap_func(5)

Ahora wrap_func se ejecutará como se explicó anteriormente y se devolverá el resultado.

Python3

from time import time
  
  
def timer_func(func):
    # This function shows the execution time of 
    # the function object passed
    def wrap_func(*args, **kwargs):
        t1 = time()
        result = func(*args, **kwargs)
        t2 = time()
        print(f'Function {func.__name__!r} executed in {(t2-t1):.4f}s')
        return result
    return wrap_func
  
  
@timer_func
def long_time(n):
    for i in range(n):
        for j in range(100000):
            i*j
  
  
long_time(5)

Producción:

Function 'long_time' executed in 0.0219s

Publicación traducida automáticamente

Artículo escrito por suryanshyadav y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *