Like python dicts but don’t like to type quotes and brackets? Try an AttributeDict!

I prefer the attribute-style method of accessing variables in a python object, and so I searched for a way to convert a Dict into an object with attribute-accessible variables automatically created from a nested Dict. This means you access a variable with object.value instead of object["value"] – and I want to go with object.value.subvalue instead of object["value"]["subvalue"]. Those brackets and quotes get annoying after awhile. I found several possible solutions, but nothing both could correctly handle multiple layers and was very lightweight. So I made up my own solution:

class AttributeDict(object):
    """
    A class to convert a nested Dictionary into an object with key-values
    accessibly using attribute notation (AttributeDict.attribute) instead of
    key notation (Dict["key"]). This class recursively sets Dicts to objects,
    allowing you to recurse down nested dicts (like: AttributeDict.attr.attr)
    """
    def __init__(self, **entries):
        self.add_entries(**entries)

    def add_entries(self, **entries):
        for key, value in entries.items():
            if type(value) is dict:
                self.__dict__[key] = AttributeDict(**value)
            else:
                self.__dict__[key] = value

    def __getitem__(self, key):
        """
        Provides dict-style access to attributes
        """
        return getattr(self, key)

The idea is to load a yaml config file, and then use an object representation to make it easy to interact with those configuration options in a python script.

To use, just load up a yaml file (or any Dict, actually), and pass it to AttributeDict.

import yaml
y = yaml.load(open(yaml_config_file, 'r'))
myobj = AttributeDict(**y)

Now you can access nested yaml variables object-style! To make it even more useful, write a child class that extends AttributeDict and can do even more stuff with your variables. I’ve included a slightly more feature-rich version of this in pypiper. If you search around for awhile, you can find various other implementations of this, but this was the only one that was both: 1. small enough to just paste at the top of something and start using right away; and 2. handles nested dictionaries correctly.