I can not figure out how to write a decorator to detect the execution time of the function generator. For an ordinary function, everything is clear:

def decor(func): def wrapper(*args,**kwargs): time_start = time.time() f = func(*args,**kwargs) time_finish = time.time()-time_start print(time_finish) return f return wrapper 

However, if you apply this to the generator, returns, as far as I understand, not the execution time, but the creation time of the generator object.

I found this solution:

 t1 = timeit.Timer(stmt="list(f(50))", setup="from __main__ import f") print t1.timeit() 

But I want to understand how to write. I understand that it is necessary to sum up the execution time for all the elements of the generator, but how to do it - I do not think about it.

    2 answers 2

    For Python> = 3.3, I would simply yield from (this is almost like yield in a for loop, but smarter)

     import time def decor(func): def generator_wrapper(*args, **kwargs): time_start = time.time() gen = func(*args, **kwargs) yield from gen time_finish = time.time()-time_start print(time_finish) return generator_wrapper @decor def myfunc(): for i in range(1, 4): time.sleep(i) yield i time.sleep(1.77) # просто так print(list(myfunc())) 

    Conclusion:

     7.775537967681885 [1, 2, 3] 

      It is enough to overload the __next__ method, called when trying to get the following generator element:

       import time class Timer: def __init__(self, gen): self.gen = gen def __next__(self): start = time.time() value = next(self.gen) print(time.time() - start) return value def timer(fn): def inner(*args, **kwargs): return Timer(fn(*args, **kwargs)) return inner