Python ProgrammingPython Programming

How to make a chain of function decorators?

Decorators have a very explicit syntax, which makes them easier to spot than helper function calls that may be arbitrarily far-removed from the subject functions or classes. Decorators offer some advantages in terms of both code maintenance and consistency.
def benchmark(func):
    """
    A decorator that prints the time a function takes
    to execute.
    """
    import time
 
    def wrapper(*args, **kwargs):
        t = time.clock()
        res = func(*args, **kwargs)
        print("{0} {1}".format(func.__name__, time.clock()-t))
        return res
    return wrapper
 
 
def logging(func):
    """
    A decorator that logs the activity of the script.
    (it actually just prints it, but it could be logging!)
    """
    def wrapper(*args, **kwargs):
        res = func(*args, **kwargs)
        print("{0} {1} {2}".format(func.__name__, args, kwargs))
        return res
    return wrapper
 
 
def counter(func):
    """
    A decorator that counts and prints the number of times a
    function has been executed
    """
    def wrapper(*args, **kwargs):
        wrapper.count = wrapper.count + 1
        res = func(*args, **kwargs)
        print("{0} has been used: {1}x".format(func.__name__, wrapper.count))
        return res
    wrapper.count = 0
    return wrapper
 
 
@counter
@benchmark
@logging
def letter_range(start, stop, step=1):
    start = ord(start.lower())
    stop = ord(stop.lower())
    for str_lst in range(start, stop, step):
        yield chr(str_lst)
 
 
print(list(letter_range("a", "f")))
print('\n')
print(list(letter_range("m", "z", 2)))
 
Sample output of above program.
letter_range ('a', 'f') {}
wrapper 0.0009437184107374183
wrapper has been used: 1x
['a', 'b', 'c', 'd', 'e']


letter_range ('m', 'z', 2) {}
wrapper 3.131164480070134e-05
wrapper has been used: 2x
['m', 'o', 'q', 's', 'u', 'w', 'y']