i don't know pylons, but it seems the way you wrote your decorator is not good.
a decorator is a callable which must return a callable. the decorator is called at the moment the function is defined, and it should return a callable (generally a function) which will be called in place of the function being decorated.
in your sample, your decorator returns a callable only if the user is authenticated at the moment the index()
function is defined.
try rewriting it this way:
def authenticate(func):
def call(*args, **kwargs):
if user['authenticated'] is True:
return func(*args,**kwargs)
else:
return redirect_to(controller='login', action='index')
return call
here, authenticate()
defines an inner function, which is returned in place of the function it decorates. now when you decorate a function using this decorator:
@authenticate
def index(self):
return render('/index.mako' )
this means that each time you call index()
, you are in fact calling the inner function declared in your decorator.
you should note that: due to the way functions are defined in python, the function object returned by the decorator still remembers the value of arguments of the function in which it was defined. call()
still knows about the argument func
which was passed when the decorator was called. (this is called a closure)
decorators are difficult to understand although they are not complicated. you should search google for a tutorial on decorators: there are plenty of them which gives a very nice understanding of the concept, far much clearer than the python documentation.