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.)
解决方案
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)
super(dotdictify, self).__setitem__.(self, key, value)
def __getitem__(self, key):
found = self.get(key, dotdictify.marker)
if found is dotdictify.marker:
found = dotdictify()
super(dotdictify, self).__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