Python: Automatically initialize instance variables?
Question: I have a python class that looks like this:

    
    
    class Process:
        def __init__(self, PID, PPID, cmd, FDs, reachable, user):
    

followed by:

    
    
            self.PID=PID
            self.PPID=PPID
            self.cmd=cmd
            ...
    

Is there any way to autoinitialize these instance variables, like C++'s
initialization list? It would spare lots of redundant code.


Answer: **Edit: extended the solution to honor default arguments also**

Here is the complete solution:

    
    
    from functools import wraps
    import inspect
    
    
    def initializer(func):
        """
        Automatically assigns the parameters.
    
        >>> class process:
        ...     @initializer
        ...     def __init__(self, cmd, reachable=False, user='root'):
        ...         pass
        >>> p = process('halt', True)
        >>> p.cmd, p.reachable, p.user
        ('halt', True, 'root')
        """
        names, varargs, keywords, defaults = inspect.getargspec(func)
    
        @wraps(func)
        def wrapper(self, *args, **kargs):
            for name, arg in list(zip(names[1:], args)) + list(kargs.items()):
                setattr(self, name, arg)
    
            for name, default in zip(reversed(names), reversed(defaults)):
                if not hasattr(self, name):
                    setattr(self, name, default)
    
            func(self, *args, **kargs)
    
        return wrapper
    

* * *

**Edit: Adam asked me to extend the solution to support keyword arguments**

    
    
    from functools import wraps
    import inspect
    
    def initializer(fun):
       names, varargs, keywords, defaults = inspect.getargspec(fun)
       @wraps(fun)
       def wrapper(self, *args, **kargs):
           for name, arg in zip(names[1:], args) + kargs.items():
               setattr(self, name, arg)
           fun(self, *args, **kargs)
       return wrapper
    

* * *

You can use a decorator:

    
    
    from functools import wraps
    import inspect
    
    def initializer(fun):
        names, varargs, keywords, defaults = inspect.getargspec(fun)
        @wraps(fun)
        def wrapper(self, *args):
            for name, arg in zip(names[1:], args):
                setattr(self, name, arg)
            fun(self, *args)
        return wrapper
    
    class process:
        @initializer
        def __init__(self, PID, PPID, cmd, FDs, reachable, user):
            pass
    

Output:

    
    
    >>> c = process(1, 2, 3, 4, 5, 6)
    >>> c.PID
    1
    >>> dir(c)
    ['FDs', 'PID', 'PPID', '__doc__', '__init__', '__module__', 'cmd', 'reachable', 'user'
    

