Python 101: How to Change a Dict Into a Class

I work with a lot of dictionaries at my job. Sometimes the dictionaries get really complicated with lots of nested data structures embedded within them. Recently I got a little tired of trying to remember all the keys in my dictionaries so I decided to change one of my dictionaries into a class so I could access the keys as instance variables / attributes. If you’ve ever gotten sick

Here’s one simple way to do it:

########################################################################
class Dict2Obj(object):
    """
    Turns a dictionary into a class
    """

    #----------------------------------------------------------------------
    def __init__(self, dictionary):
        """Constructor"""
        for key in dictionary:
            setattr(self, key, dictionary[key])
        
    
#----------------------------------------------------------------------
if __name__ == "__main__":
    ball_dict = {"color":"blue",
                 "size":"8 inches",
                 "material":"rubber"}
    ball = Dict2Obj(ball_dict)

This code uses setattr to add each of the keys as attributes to the class. The following shows some examples of how it works:

>>> ball.color
'blue'
>>> ball.size
'8 inches'
>>> print ball
<__main__.Dict2Obj object at 0x028CD5B0>

When we print the ball object, we get a rather unhelpful string back from the class. Let’s override the __repr__ method of our class and make it print out something a little more useful:

########################################################################
class Dict2Obj(object):
    """
    Turns a dictionary into a class
    """

    #----------------------------------------------------------------------
    def __init__(self, dictionary):
        """Constructor"""
        for key in dictionary:
            setattr(self, key, dictionary[key])
        
    #----------------------------------------------------------------------
    def __repr__(self):
        """"""
        return "" % self.__dict__
    
#----------------------------------------------------------------------
if __name__ == "__main__":
    ball_dict = {"color":"blue",
                 "size":"8 inches",
                 "material":"rubber"}
    ball = Dict2Obj(ball_dict)

Now if we print out the ball object, we’ll get the following:

>>> print ball

This is a little unintuitive in that it is printing out a dictionary using the class’s internal __dict__ rather than just the attribute names. This is more a matter of taste than anything, but let’s try to get just the method names:

########################################################################
class Dict2Obj(object):
    """
    Turns a dictionary into a class
    """

    #----------------------------------------------------------------------
    def __init__(self, dictionary):
        """Constructor"""
        for key in dictionary:
            setattr(self, key, dictionary[key])
        
    #----------------------------------------------------------------------
    def __repr__(self):
        """"""
        attrs = str([x for x in self.__dict__])
        return "" % attrs
    
#----------------------------------------------------------------------
if __name__ == "__main__":
    ball_dict = {"color":"blue",
                 "size":"8 inches",
                 "material":"rubber"}
    ball = Dict2Obj(ball_dict)

Here we just loop over the contents of __dict__ and return a string with just a list of the keys, which match up with the attribute names. You could have also done it like this:

attrs = str([x for x in dir(self) if "__" not in x])

I’m sure there are lots of other ways to accomplish this sort of thing as well. Regardless, I found this little piece of code helpful in some of my work. Hopefully you’ll find it useful too.

8 thoughts on “Python 101: How to Change a Dict Into a Class”

  1. If this is really quick and dirty, you can even do:

    self.__dict__.update(dictionary)

    Instead of the for loop.

    But I would actually keep the for loop and add a dependy injection :

    def __init__(self, dictionary, merge=lambda s, k, v: setattr(s, k, v)):
    for k, v in dictionary.iteritems():
    merge(self, k, v)

    This would allow to override the attribute setting, this way, if there is an attribute you actually don’t want to override if it already exits, you can.

  2. Hi there, very interesting! I would change the title of the post… since you are not creating classes, but objects or instances of Dict2Obj class… just a small detail 🙂
    Nicely explained!!

  3. or if you really just want to quickly convert your dict to an object so you can access the items as attributes and don’t care about the repr method: ball = type(‘D’, (object,), ball_dict)()

  4. Thanks a lot for this. Very neat trick which I belive could be especially usefuly in django for creating objects from JSON dicts to display inside a template. Thanks a million for this very neat trick

Comments are closed.