Devraj wrote: > Hi all, > > I am trying to simply my Web application handlers, by using Python > decorators. > > Essentially I want to use decorators to abstract code that checks for > authenticated sessions and the other that checks to see if the cache > provider (Memcache in this instance) has a suitable response. > > Consider this method definition with the decorators: > > @auth.login_required > @cache.clear > def post(self, facility_type_id = None): > > auth.login_required checks to see if the user is logged in, otherwise > returns an appropriate error message, or executes the original > function. > > cache.clear would check to to see if the cache has a particular key > and drop that, before it executes the calling method. > > Both auth.login_required and cache.clear would want to eventually > execute the calling method (post). > > From what I've read both, doing what I am doing now would execute the > calling method (post) twice. > > My question, how do I chain decorators that end up executing the > calling method, but ensure that it's only called once.
You typically don't need to do anything special for the above to work: >>> def v(f): ... print "decorator v, wrapping", f.__name__, "into a" ... def a(*args, **kw): ... print "calling", f.__name__, "from a" ... return f(*args, **kw) ... return a ... >>> def w(f): ... print "decorator w, wrapping", f.__name__, "into b" ... def b(*args, **kw): ... print "calling", f.__name__, "from b" ... return f(*args, **kw) ... return b ... >>> @v ... @w ... def f(s): ... print s ... decorator w, wrapping f into b decorator v, wrapping b into a >>> f("hello") calling b from a calling f from b hello The output shows that w wraps f into b, but v then doesn't get to see the original f, it wraps b into a. Put another way @v @w def f(): ... is the same as def f(): ... f = v(w(f)) and calling f() now is equivalent to calling a() which may or may not invoke b() which may or may not invoke the original f(). Translated into your example: def post(self, facility_type_id = None): ... post = auth.login_required(cache.clear(post)) The cache should only be cleared after a successful login, and the original post() will only be invoked after a successful login and with a cleared cache. -- http://mail.python.org/mailman/listinfo/python-list