2

I have a code:

from functools import wraps

def my_decorator(f):
    @wraps(f)
    def wrapper(*args, **kwargs):
        print kwargs["name"] # Should display Dean Armada
        print 'Calling decorated function'
        return f(*args, **kwargs)
    return wrapper

@my_decorator(name="Dean Armada")
def example():
    """Docstring"""
    print 'Called example function'

example()

What I want to achieve is for my decorator to depend on the kwargs arguments as all of its parameter.. My code above throws this error

my_decorator() got an unexpected keyword argument 'name'
Pablo
  • 4,821
  • 12
  • 52
  • 82
Dean Christian Armada
  • 6,724
  • 9
  • 67
  • 116
  • Create another (outer) layer that accepts a `name` argument, and pass that on to `wrapper`. –  Aug 10 '16 at 01:36

1 Answers1

6

You can have separate arguments for your decorator in the following way:

from functools import wraps


def my_decorator(**decorator_kwargs):  # the decorator
    print decorator_kwargs['name']

    def wrapper(f):  # a wrapper for the function
        @wraps(f)
        def decorated_function(*args, **kwargs):  # the decorated function
            print 'Calling decorated function'
            return f(*args, **kwargs)
        return decorated_function
    return wrapper


@my_decorator(name='Dean Armada')
def example(string):
    print string


if __name__ == '__main__':
    example('Print this!')

Running this produces the output:

Dean Armada
Calling decorated function
Print this!

Also note that decorator_kwargs is accessible from wrapper and decorated_function as well if needed.

Karin
  • 8,404
  • 25
  • 34