我希望能够执行以下操作:
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':{}}
我的动机是提高代码的简洁性,并在可能的情况下使用类似于Javascript的语法来访问JSON对象,以进行高效的跨平台开发。(我也使用Py2JS和类似的东西。)
这是一种创建这种体验的方法:
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__(key, value) def __getitem__(self, key): found = self.get(key, DotDictify.MARKER) if found is DotDictify.MARKER: found = DotDictify() super(DotDictify, self).__setitem__(key, found) return found __setattr__, __getattr__ = __setitem__, __getitem__ if __name__ == '__main__': life = {'bigBang': {'stars': {'planets': {} # Value changed from [] } } } life = DotDictify(life) print(life.bigBang.stars.planets) # -> [] life.bigBang.stars.planets.earth = {'singleCellLife' : {}} print(life.bigBang.stars.planets) # -> {'earth': {'singleCellLife': {}}}