import functools


def friendly_decorator(f):
    """Transform a decorated function into a decorator that can be called with or without parameters.

    The returned function wraps a decorator function such that it can be invoked
    with or without parentheses such as:

        @decorator(with, arguments, and=kwargs)
        or
        @decorator
    """

    @functools.wraps(f)
    def decorator(*args, **kwargs):
        if len(args) == 1 and len(kwargs) == 0 and callable(args[0]):
            # actual decorated function
            return f(args[0])
        else:
            # decorator arguments
            return lambda realf: f(realf, *args, **kwargs)

    return decorator