PEP documentation: http://legacy.python.org/dev/peps/pep-0318/

    Decorators are a way to execute code before and after your code executes. For example:

    def decorator(func):
        def inner_func():
            print('executing function now!')
            func()
            print('your function has completed execution!')
        return inner_func
    
    def print_hi():
        print("hello!")
        
    decorated_function = decorator(print_hi)
    decorated_function()
    

    Because functions are objects, it is possible to pass them around as parameters. The resulting output of running this is as follows:

    executing function now.
    hello!
    your function has completed execution
    

    You can shorten this to be a decorator like so:

    from functools import wraps
    def decorator(func):
        @wraps(func)
        def inner_func():
            print('executing function now!')
            func()
            print('your function has completed execution!')
        return inner_func
        
    @decorator
    def printy():
        print("hello!")
    

    this will use the function below it as the func parameter. The resulting output will be the same.