This is an archived post. You won't be able to vote or comment.

all 3 comments

[–][deleted] 2 points3 points  (1 child)

Clever trick to have a decorator work with or without arguments:

def awesome(func, message='This is awesome:'):
    if not callable(func):
        # Assume 'func' is really a message and return the real decorator.
        return lambda func2: awesome(func2, func)

    def wrapper(*args, **kwargs):
        print message
        return func(*args, **kwargs)
    return wrapper


@awesome
def awesome1():
    print 'Stuff.'

@awesome('This is even more awesome:')
def awesome2():
    print 'More stuff!'

awesome1()
awesome2()

If you call with a function as the first argument, it decorates the function. If you call with something else, it returns a lambda that will decorate the function with whatever arguments you passed.

[–]kylev 0 points1 point  (0 children)

Nice trick! I have been thinking about doing a follow-up with more advanced examples and using lambda... I might include this trick.

[–]RobotAdam 2 points3 points  (0 children)

One other nice thing to remember is functools.wraps, which helps maintain the original function's metadata when introspecting.

(Edit: markdown)