On Fri, Jul 23, 2010 at 6:49 AM, George Sakkis email@example.com wrote:
On Thu, Jul 22, 2010 at 10:21 PM, geremy condra firstname.lastname@example.org wrote:
I would also argue that the more valid comparison would be nested functions or classes- both perfectly pretty constructs on their own- which would cause me to gnaw on otherwise unoffending office furniture if I encountered them nested 3 deep.
I guess you're not much fond of decorators then; it's common to define them exactly as 3-level deep nested functions:
def decofactory(deco_arg): def decorator(func): def wrapper(*args, **kwargs): if deco_arg: return func(*args, **kwargs) return wrapper return decorator
@decofactory(n) def func(x, y): ...
Actually, I think that's the main reason why parameterised decorators can be such a pain to understand - keeping the 3 scopes straight in your head is genuinely difficult. There's a reason the recently added contextlib.ContextDecorator is implemented as a class with a __call__ method rather than using nested functions.
A given clause would let you reorder this code, and I think doing so is genuinely clearer:
def decofactory(deco_arg): return decorator given: def decorator(func): if not deco_arg: return func return wrapper given: @wraps(func) def wrapper(*args, **kwargs): return func(*args, **kwargs)
Reversing the order of some aspects of the execution allows the text flow to match the way you would describe the operation: we have a decorator factory that returns a decorator that returns the function unmodified if deco_arg evaluates to False and returns a wrapper around the decorated function otherwise.