Search code examples
pythonclassinitialization-list

Automatically initialize instance variables?


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.


Solution

  • You can use a decorator:

    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
    

    Use it to decorate the __init__ method:

    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'