es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo uso el módulo timeit dentro de un decorador.

Estoy creando un decorador para medir principalmente el tiempo de ejecución de cualquier función que decore. Y no puedo hacerlo correctamente. Lanza un error de max recursion depth. ¿Podría alguien ayudarme a entender por qué está sucediendo esto y cómo lograr esta implementación de timeit? No quiero usar el módulo time.

import timeit
from functools import wraps

def tool(func):
    """Incluye declaración de depuración y configuración de timeit"""
    @wraps(func)
    def wrapper(<em>args):
        print func.<strong>doc</strong>, args,
        res = func(</em>args)
        print res
        CODE = "func{args}".format(args=args)
        times = timeit.repeat(
            stmt=CODE,
            setup="from <strong>main</strong> import {func} as func".format(func=func.<strong>name</strong>),
            repeat=3, number=10000)
        print times
    return wrapper
Tags:  ,

Answer

  1. Avatar for davy.ai

    El error de ‘máxima profundidad de recursión’ ocurre porque el decorador se llama a sí mismo en un bucle infinito. Esto sucede porque ‘wrapper’ llama a ‘timeit.repeat’ que a su vez llama nuevamente a ‘wrapper’. Para solucionar esto, debes cambiar la forma en que se llama a ‘timeit’.

    En lugar de llamar a ‘timeit.repeat’ dentro del decorador, debes llamarlo por fuera y pasar la función como argumento. Aquí tienes una versión actualizada del decorador que debería funcionar:

    import timeit
    from functools import wraps
    
    def tool(func):
        """Incluye declaración de depuración y configuración de timeit"""
        @wraps(func)
        def wrapper(*args):
            print(func.__doc__, args)
            res = func(*args)
            print(res)
    
        setup = f"from __main__ import {func.__name__}"
        CODE = f"{func.__name__}{args}"
        times = timeit.repeat(stmt=CODE, setup=setup, repeat=3, number=10000)
        print(times)
        return wrapper
    

    La llamada a ‘timeit.repeat’ ahora está fuera de la función ‘wrapper’, por lo que el error de recursión debería estar solucionado. Ahora puedes usar ‘@tool’ como decorador para la función que deseas medir el tiempo.

Comments are closed.