On Thu, 24 Feb 2005 15:00:46 -0700, Steven Bethard <[EMAIL PROTECTED]> wrote: > Tom Willis wrote: > > Question on decorators in general. Can you parameterize those? > > > > If I wanted to something and after the function call for example, I > > would expect something like this would work. > > > > def prepostdecorator(function,pre,post): > > def wrapper(*args,**kwargs): > > pre() > > result = function(*args,**kwargs) > > post() > > return result > > return wrapper > > > > def dopre(): > > print "call pre" > > > > def dopost(): > > print "call post" > > > > @prepostdecorator(pre,post) > > def sayhello(Name): > > print "Hey %s, nice to meet you" % Name > > > > #sayhello = prepostdecorator(sayhello,dopre,dopost) > > > > if __name__=="__main__": > > sayhello("Dude") > > > > but I get ... > > TypeError: prepostdecorator() takes exactly 3 arguments (2 given) > > You get this TypeError for the same reason that I get the following > TypeError: > > py> def prepostdecorator(function, pre, post): > ... pass > ... > py> prepostdecorator(1, 2) > Traceback (most recent call last): > File "<interactive input>", line 1, in ? > TypeError: prepostdecorator() takes exactly 3 arguments (2 given) > > The expression after @ is a _normal Python expression_. So since you > couldn't call prepostdecorator with 2 arguments in any other situation, > you still can't. > > If you want to call prepostdecorator with 2 arguments, you need to write > it this way. A few options: > > (1) Use nested functions: > > py> def prepostdecorator(pre,post): > ... def decorator(function): > ... def wrapper(*args,**kwargs): > ... pre() > ... result = function(*args,**kwargs) > ... post() > ... return result > ... return wrapper > ... return decorator > ... > py> @prepostdecorator(dopre, dopost) > ... def sayhello(name): > ... print "Hey %s, nice to meet you" % name > ... > py> sayhello('Tom') > call pre > Hey Tom, nice to meet you > call post > > (2) Use functional.partial (PEP 309[1]) > > py> def prepostdecorator(pre, post, function): > ... def wrapper(*args,**kwargs): > ... pre() > ... result = function(*args,**kwargs) > ... post() > ... return result > ... return wrapper > ... > py> @partial(prepostdecorator, dopre, dopost) > ... def sayhello(name): > ... print "Hey %s, nice to meet you" % name > ... > py> sayhello('Tom') > call pre > Hey Tom, nice to meet you > call post > > (3) Use a class: > > py> class prepostdecorator(object): > ... def __init__(self, pre, post): > ... self.pre, self.post = pre, post > ... def __call__(self, function): > ... def wrapper(*args,**kwargs): > ... self.pre() > ... result = self.function(*args,**kwargs) > ... self.post() > ... return result > ... return wrapper > py> @prepostdecorator(dopre, dopost) > ... def sayhello(name): > ... print "Hey %s, nice to meet you" % name > ... > py> sayhello('Tom') > call pre > Hey Tom, nice to meet you > call post > > Note that in all of the above cases, the result of evaluating the > expression after the @ is a callable object that takes _exactly one_ > argument, the function to be decorated. > > HTH, > > STeVe > > [1] http://www.python.org/peps/pep-0309.html > -- > http://mail.python.org/mailman/listinfo/python-list > Wow thanks for the explanation!! Some of it is a bit mind bending to me at the moment , but I'm going to mess with it a bit.
-- Thomas G. Willis http://paperbackmusic.net -- http://mail.python.org/mailman/listinfo/python-list