When using decorators, you should familiarize yourself with functools.wraps
. Consider the difference in available informations between these two (useless) decorators:
from functools import wraps
def decorate1(func):
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
def decorate2(func):
@wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
When applied to a function:
@decorate1
def test1(x, y, z):
"test1 docstring"
print(x, y, z)
@decorate2
def test2(x, y, z):
"test2 docstring"
print(x, y, z)
The help on each function look quite different:
>>> help(test1)
Help on function wrapper in module __main__:
wrapper(*args, **kwargs)
>>> help(test2)
Help on function test2 in module __main__:
test2(x, y, z)
test2 docstring
Since you’re using Python 3, you should consider using better timing primitives. Namely time.perf_counter()
:
def wrapper(*args, **kwargs):
begin = time.perf_counter()
res = original_function(*args, **kwargs)
elapsed = time.perf_counter() - begin
Lastly, you should consider using format
all along instead of string concatenation:
import time
import colorama
from functools import wraps
def timeit_decorator(original_function):
@wraps(original_function)
def wrapper(*args, **kwargs):
begin = time.perf_counter()
result = original_function(*args, **kwargs)
elapsed = time.perf_counter() - begin
print("Function {color}{}{reset} executed in {color}"
"~{:.2f}{reset} minutes!"
.format(
original_function.__name__,
elapsed / 60,
color=colorama.Fore.GREEN,
reset=colorama.Style.RESET_ALL))
return result
return wrapper