[Sorry, my Firefox destroyed the indent... Am 14.09.2012 22:29 schrieb Terry Reedy:
In other words def make_wrapper(func, param): def wrapper(*args, **kwds): for i in range(param): func(*args, **kwds) return wrapper def f(x): print(x) f = make_wrapper(f, 2) f('simple') # is simpler, at least for some people, than the following # which does essentially the same thing. def make_outer(param): def make_inner(func): def wrapper(*args, **kwds): for i in range(param): func(*args, **kwds) return wrapper return make_inner @make_outer(2) def f(x): print(x) f('complex')
For this case, my mydeco.py which I use quite often contains a def indirdeco(ind): # Update both the outer as well as the inner wrapper. # If we knew the inner one was to be updated with something # from *a, **k, we could do it. But not this way... @functools.wraps(ind) def outer(*a, **k): @functools.wraps(ind) def inner(f): return ind(f, *a, **k) return inner return outer so I can do @indirdeco def make_wrapper(func, param): @functools.wraps(func) def wrapper(*args, **kwds): for i in range(param): func(*args, **kwds) return wrapper and then nevertheless @make_wrapper(2) def f(x): print(x) BTW, I also have a "meta-decorator" for the other direction: def wrapfunction(mighty): """Wrap a function taking (f, *a, **k) and replace it with a function taking (f) and returning a function taking (*a, **k) which calls our decorated function. Other direction than indirdeco.""" @functools.wraps(mighty) def wrapped_outer(inner): @functools.wraps(inner) def wrapped_inner(*a, **k): return mighty(inner, *a, **k) wrapped_inner.func = inner # keep the wrapped function wrapped_inner.wrapper = mighty # and the replacement return wrapped_inner wrapped_outer.func = mighty # keep this as well return wrapped_outer With this, a @wrapfunction def twice(func, *a, **k): return func(*a, **k), func(*a, **k) can be used with @twice def f(x): print (x); return x very nicely. Thomas -- http://mail.python.org/mailman/listinfo/python-list