Diez B. Roggisch wrote: > However I've encountered one peculiarity that strikes me odd: > > When one writes a decorated function like this: > > @decorate > def foo(): > pass > > the function decorate usually looks like this: > > def decorate(func): > def _d(*args, **kwargs): > do_something() > # call func > func(*args, **kwargs) > return _d > > So the function decorator has to return a function that is bound to the name > foo in the originating context (module or class) and gets the function > passed as argument. > > But if I want my decorator to be parametrized, it looks like this: > > @decorate(arg) > def foo(): > pass > > def decorate(arg): > def f(func): > def _d(*args, **kwargs): > do_something(arg) > # call func > func(*args, **kwargs) > return _d > > So what happens is that an decorater with arguments is called with these, > returns a callable that then is called with foo, and the result is stored > under foo.
the decorator itself must be a callable, so to create parameterized decorators, you have to create a callable that returns a callable. due to some weird obsession with nested functions and lexical scoping, most decorator examples use functions inside functions inside functions, but you can of course use a good old class instead: class decorator: def __init__(self, params): # save the parameters def __call__(self, func): # decorate the function return func @decorator(params) def func(...): pass or even: class decorator: def __init__(self, params): # save the parameters def __call__(self, func): self.func = func return self.handler def handler(self, *args): # do something self.func(*args) # do something </F> -- http://mail.python.org/mailman/listinfo/python-list