Search code examples
pythonattributesdecoratorpython-decorators

Decorator to set any number of attributes of callable


I need a Python decorator to add any number of named attributes to the decorated callable.

For example:

@attributes(foo='this', bar='exactly')  # <-- Implement this decorator!
def fun1(i):
   return i * 2

assert fun1.foo == 'this'
assert fun1.bar == 'exactly'

There exists a similar question, the answers to which deal with setting a single attribute with a fixed name. It doesn't apply here for setting an arbitrary number of attributes.

This doesn't work:

def attributes(**kwargs):
    def _inner(func):
        for k, v in kwargs.items():
            func.k = v
        return func
    return _inner

Solution

  • Here is a function that implements the decorator:

    def attributes(**kwargs):
        def _inner(func):
            for k, v in kwargs.items():
                setattr(func, k, v)
            return func
        return _inner
    

    Alternatively, here is a class that implements the decorator:

    class attributes:
        def __init__(self, **kwargs):
            self.kwargs = kwargs
    
        def __call__(self, func):
            for k, v in self.kwargs.items():
                setattr(func, k, v)
            return func