~/Untitled.html
Python Decorators in action
I never really knew or understood why we actually needed python decorator functions in the first place. But after a brief stint with django, I do.
One of the good reasons to use decorators is for a purpose called Aspect Oriented Programming – those of you who know and use the Spring framework might be familiar with it – it’s the practice of isolating various Aspects of your job into a seaparate MOdule , or function. E.g: SEcurity, LOgging, etc.
If all of your function require that a user be logged in before he be able to execute that function – you can take two ways – check whether the user is blacklisted in every function, by writing 2-3 lines of code, or you can use decorator functions like this :
def check_whether_user_is_blacklisted(func):
def inner(*args, **kwargs):
if kwargs['username'] == 'Ramm':
print "Sorry, Ramm is not allowed on our site."
else:
func(*args, **kwargs)
return inner
@check_whether_user_is_blacklisted
def myfunc(username="Stein"):
print "Hey %s, you're logged in !" % ( username)
myfunc("test")
myfunc("Ramm")
Note the @ syntax – similar to java – was adopted after python 2.4 ( we’re in the age of python 3k, so no worries – you probably have python 2.4 installed. )
the myfunc ( a function object ) is automatically passed to check_whether_user_is_authenticated as the argument, and that function instead replaces myfunc with another function defined inside it – inner.
The inner function, as you can see – applies an additional check to see whether the user is blacklisted or not. If not, it executes the original function myfunc. If he is blacklisted, the function prints a message and exits.
so,
myfunc(“test”) – will print “Hey test, you’re logged in!”
myfunc(“Ramm”) – will print, “Sorry, Ramm is not allowed on our site.”
So, just by adding a line “@check_whether_user_is_blacklisted” before any of our functions that we don’t want blacklisted users to be able to execute, we can achieve this effect.
[ Courtesy SmileyChris ]:
Here’s another hint, use “wraps” to make the decorated function retain the docstring and any other view attributes:
from django.utils.functional import wraps
def check_whether_user_is_blacklisted(func):
@wraps(func)
def inner(*args, **kwargs):
Happy decorating !
-anonymouscowherd
SmileyChris said
Here’s another hint, use “wraps” to make the decorated function retain the docstring and any other view attributes:
from django.utils.functional import wraps
def check_whether_user_is_blacklisted(func):
@wraps(func)
def inner(*args, **kwargs):
anonymouscowherd said
Thanks – tried it and it works
Gadget_Blog said
Great post.. this is really a great information..This will be useful post.. I will
comeback for more..
Cheers,
gadgettechblog.com