Search code examples
pythonclassargumentsself

class, dict, self, init, args?


class attrdict(dict):
    def __init__(self, *args, **kwargs):
        dict.__init__(self, *args, **kwargs)
        self.__dict__ = self

a = attrdict(x=1, y=2)
print a.x, a.y

b = attrdict()
b.x, b.y  = 1, 2
print b.x, b.y

Could somebody explain the first four lines in words? I read about classes and methods. But here it seems very confusing.


Solution

  • You are not using positional arguments in your example. So the relevant code is:

    class attrdict(dict):
        def __init__(self, **kwargs):
            dict.__init__(self, **kwargs)
            self.__dict__ = self
    

    In the first line you define class attrdict as a subclass of dict. In the second line you define the function that automatically will initialize your instance. You pass keyword arguments (**kargs) to this function. When you instantiate a:

     a = attrdict(x=1, y=2)
    

    you are actually calling

    attrdict.__init__(a, {'x':1, 'y':2})
    

    dict instance core initialization is done by initializing the dict builtin superclass. This is done in the third line passing the parameters received in attrdict.__init__. Thus,

    dict.__init__(self,{'x':1, 'y':2})
    

    makes self (the instance a) a dictionary:

    self ==  {'x':1, 'y':2}
    

    The nice thing occurs in the last line: Each instance has a dictionary holding its attributes. This is self.__dict__ (i.e. a.__dict__).

    For example, if

    a.__dict__ = {'x':1, 'y':2} 
    

    we could write a.x or a.y and get values 1 or 2, respectively.

    So, this is what line 4 does:

    self.__dict__ = self
    

    is equivalent to:

    a.__dict__ = a  where a = {'x':1, 'y':2}
    

    Then I can call a.x and a.y.

    Hope is not too messy.