mardi 22 mars 2016

Is there a pattern for a function that either is a decorator or returns a decorator? [duplicate]

This question already has an answer here:

Say I have a decorator that can optionally take an argument. Something like:

def multiplies_it(arg=2):
    def decorator(f):
        def wrapped(x):
            return f(x * arg)
        return wrapped
    return decorator

This works with @multiplies_it(2) or @multiplies_it(), but not @multiplies_it.

To make it work in the latter case also (using that default argument of 2) I'd have to do something like:

def multiplies_it(arg_or_f=2):
    def decorator(f):
        def wrapped(x):
            return f(x * arg)
        return wrapped

    if hasattr(arg_or_f, '__call__'):
        arg = 2
        return decorator(arg_or_f)
    else:
        arg = arg_or_f
        return decorator

This isn't quite as clean, and looks very formulaic and boilerplate, which in Python means it can of course likely be abstracted away.

Is there any common pattern to dealing with this? It seems this must occur often, a decorator that is either called on its own or with an argument.

Aucun commentaire:

Enregistrer un commentaire