views:

91

answers:

2

I'd like to be able to do something like this:

from dotDict import dotdictify

life = {'bigBang':
    {'stars': 
        {'planets': []
        }
    }
}

dotdictify(life)

#this would be the regular way:
life['bigBang']['stars']['planets'] = {'earth': {'singleCellLife': {} }}
#But how can we make this work?
life.bigBang.stars.planets.earth = {'singleCellLife': {} }


#Also creating new child objects if none exist, using the following syntax

life.bigBang.stars.planets.earth.multiCellLife = {'reptiles':{},'mammals':{}}

My motivations are to improve the succinctness of the code, and if possible use similar syntax to Javascript for accessing JSON objects for efficient cross platform development.(I also use Py2JS and similar.)

+4  A: 

Here's one way to create this kind of experience:

class dotdictify(dict):
    marker = object()
    def __init__(self, value=None):
        if value is None:
            pass
        elif isinstance(value, dict):
            for key in value:
                self.__setitem__(key, value[key])
        else:
            raise TypeError, 'expected dict'

    def __setitem__(self, key, value):
        if isinstance(value, dict) and not isinstance(value, dotdictify):
            value = dotdictify(value)
        dict.__setitem__(self, key, value)

    def __getitem__(self, key):
        found = self.get(key, dotdictify.marker)
        if found is dotdictify.marker:
            found = dotdictify()
            dict.__setitem__(self, key, found)
        return found

    __setattr__ = __setitem__
    __getattr__ = __getitem__

life = {'bigBang' :
          {'stars':
               {'planets': {}
                }
           }
}

life = dotdictify(life)

print life.bigBang.stars.planets
life.bigBang.stars.planets.earth = { 'singleCellLife' : {} }
print life.bigBang.stars.planets
Curt Hagenlocher
Thank you for your awesomeness!
Luke Stanley
Calling dict.__setitem__(self, key, value) is the trick to the recursion I was missing! Quite elegant code there sir :)
Luke Stanley
A: 

I expanded on this question here: http://stackoverflow.com/questions/3797957/python-recursively-access-dict-get-and-set

The DotDictify solution is very nice. It would be nice to extend it just slightly (@see the link above)

Hal
This should be posted as a comment on the question, not an answer.
Mike DeSimone
Yeah, no kidding, except there are no "Add comment" link or form on the above question or answer (for me)
Hal
Thanks Hal, I'll give it a read, I definitely appreciate any improvements (Im using it here: http://github.com/lukestanley/lustdb too). A lot of credit goes to Curt Hagenlocher of course. :)
Luke Stanley