poros
10/5/2015 - 12:02 AM

Define a decorator

Define a decorator

@f1(arg)
@f2
def func(): pass
# is equivalent to
def func(): pass
func = f1(arg)(f2(func))


def my_decorator(a_function_to_decorate):
    
    @functools.wraps(a_function_to_decorate)  # preserve function's metadata
    def the_wrapper_around_the_original_function(*args, **kwargs):
        print "Before the function runs"
        return a_function_to_decorate(*args, **kwargs) # without return, function calls' return values are lost
        print "After the function runs"
    
    return the_wrapper_around_the_original_function

@my_decorator
def function(arg1, arg2):


# Passing arguments to a decorator
def my_decorator_with_arguments(arg1, arg2):
    print arg1, arg2
    def my_decorator(a_function_to_decorate):
        @functools.wraps(a_function_to_decorate)  # preserve function's metadata
        def the_wrapper_around_the_original_function(*args, **kwargs):
            print "Before the function runs"
            return a_function_to_decorate(*args, **kwargs)
            print "After the function runs"
        return the_wrapper_around_the_original_function
    return my_decorator

@my_decorator_wit_arguments(arg1, arg2)
def function(arg3, arg4=42):
  
# even if def my_decorator_with_arguments(arg1='foo', arg2='bar')
# you need to use @my_decorator_with_arguments()
# py.test fixtures has a weird trick for working both with and without parenthesis
# https://github.com/pytest-dev/pytest/blob/3404d2a99ba67b90e03bb17c1957e90869ef27a1/_pytest/python.py#L131
# basically, the first default argument is either the function or the actual argument
# (scope of the fixture). If it's callable, then use the default value for the actual argument


# simpler decorator if you don't care about manipulating the return value and the function call
def simpler_decorator(f):
    return f

def simpler_decorator_with_arguments(arg1, arg2):
   # wraps(f) is useless because we're returning the original function, not its return value
    def decorator(f):
        return f
    return decorator