Skip to content

Instantly share code, notes, and snippets.

@poros
Last active October 28, 2015 22:49
Show Gist options
  • Save poros/a94913f4fc35679b80eb to your computer and use it in GitHub Desktop.
Save poros/a94913f4fc35679b80eb to your computer and use it in GitHub Desktop.
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment