Search code examples
pythonvariable-assignmentboilerplatefunction-parameter

Assign function arguments to `self`


I've noticed that a common pattern I use is to assign SomeClass.__init__() arguments to self attributes of the same name. Example:

class SomeClass():
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

In fact it must be a common task for others as well as PyDev has a shortcut for this - if you place the cursor on the parameter list and click Ctrl+1 you're given the option to Assign parameters to attributes which will create that boilerplate code for you.

Is there a different, short and elegant way to perform this assignment?


Solution

  • Decorator magic!!

    >>> class SomeClass():
            @ArgsToSelf
            def __init__(a, b=1, c=2, d=4, e=5):
                pass
    
    >>> s=SomeClass(6,b=7,d=8)
    >>> print s.a,s.b,s.c,s.d,s.e
    6 7 2 8 5
    

    while defining:

    >>> import inspect
    >>> def ArgsToSelf(f):
        def act(self, *args, **kwargs):
            arg_names,_,_,defaults = inspect.getargspec(f)
            defaults=list(defaults)
            for arg in args:
                setattr(self, arg_names.pop(0),arg)
            for arg_name,arg in kwargs.iteritems():
                setattr(self, arg_name,arg)
                defaults.pop(arg_names.index(arg_name))
                arg_names.remove(arg_name)
            for arg_name,arg in zip(arg_names,defaults):
                setattr(self, arg_name,arg)
            return f(*args, **kwargs)
        return act
    

    Of course you could define this decorator once and use it throughout your project.
    Also, This decorator works on any object function, not only __init__.