A Refresher

Python decorators are bits of syntactic sugar that allow you to execute complementary code every time a function is executed. Given this function...

def super_useful_decorator ( fn ): def wrapper (): print "hello world" fn () return wrapper

...this:

def hello_world (): return 42 super_useful_decorator ( hello_world ())()

...is exactly the same as this:

@super_useful_decorator def hello_world (): return 42 hello_world ()

Who Cares?

At this point, most decorator tutorials wax lyrical about how python functions are first class and then spend a lot of time talking about closures. This is interesting, but not necessarily immediately useful. Here instead, is the cliffnotes version:

Function decorators let you do things automatically when you call a function.

Keeping this in mind, let's move on to an actual use case for decorators.

Authenticating API Calls

Say you're setting up a REST API which requires an authenticated token from the user:

def token_is_valid ( token ): # Replace with a call to your token validation service return token == '42' def authenticate_access ( token ): return token_is_valid ( token ) def rest_function_1 ( token , input_1 , input_2 ) rv = {} if authenticate_access ( token ): rv [ 'code' ] = 200 else : rv [ 'code] = 401 rv [ 'payload' ] = input_1 + input_2 return rv def rest_function_2 ( token , input_1 , input_2 ) rv = {} if authenticate_access ( token ): rv [ 'code' ] = 200 else : rv [ 'code' ] = 401 rv [ 'payload' ] = input_1 * input_2 return rv

This is perfectly workable code, but there are a couple of problems with it.

Boredom : Authentication code has to be written for each REST API call. This is boring for the programmer.

: Authentication code has to be written for each REST API call. This is boring for the programmer. Brittleness : Changing the authentication code in any way means that every REST API function has to be altered.

: Changing the authentication code in any way means that every REST API function has to be altered. Repetition: This follows from the last problem, but bears repetition (heh). Saying the same thing over and over in authentication code is dangerous: sooner or later, you're going to say it wrong and let a bunch of people use your service without authentication.

Python decorators are a pretty elegant solution to this problem:

def token_is_valid ( token ): # No seriously, replace this with your own validation code return token == '42' def authenticate_access ( fn ): def wrapfn ( * args , ** kwargs ): rv = {} token = args [ 0 ] if token_is_valid ( token ): rv [ 'code' ] = 200 rv [ 'payload' ] = fn ( * args , ** kwargs ) else : rv [ 'code' ] = 401 return rv return wrapfn @authenticate_access def rest_function_1 ( token , input_1 , input_2 ): return input_1 + input_2 @authenticate_access def rest_function_2 ( token , input_1 , input_2 ): return input_1 * input_2

Let's try executing this:

In [ 1 ]: rest_function_1 ( '43' , 2 , 2 ) Out [ 1 ]: { 'code' : 401 } In [ 2 ]: rest_function_1 ( '42' , 2 , 2 ) Out [ 2 ]: { 'code' : 200 , 'payload' : 4 } In [ 3 ]: rest_function_2 ( '42' , 32 , 32 ) Out [ 3 ]: { 'code' : 200 , 'payload' : 1024 }

Neat.

As an additional bonus, there is now clear separation of concerns between authentication and whatever it is the REST API functions are supposed to be doing. The code just looks cleaner.

Conclusion

If you are using Python, you should be making heavy use of decorators.

If you want to see what other people have used decorators for, the Python wiki is kind of amazing.