Skip to content

Instantly share code, notes, and snippets.

@huyx
Created January 3, 2014 09:10
Show Gist options
  • Save huyx/8235092 to your computer and use it in GitHub Desktop.
Save huyx/8235092 to your computer and use it in GitHub Desktop.
# -*- coding: utf-8 -*-
class dotdict(dict):
'''用 . 操作 dict 中的元素
>>> dd = dotdict(a=1, b=2)
>>> dd.c = 3
>>> dd
{'a': 1, 'c': 3, 'b': 2}
>>> del dd.c
>>> dd
{'a': 1, 'b': 2}
'''
def __getitem__(self, name):
value = dict.__getitem__(self, name)
if isinstance(value, dict) and not isinstance(value, dotdict):
value = dotdict(value)
return value
__getattr__ = __getitem__
__setattr__ = dict.__setitem__
__delattr__ = dict.__delitem__
class dotdict2(dotdict):
'''dotdict 的扩展,支持多级直接赋值
>>> ddx = dotdict2()
>>> ddx[1][1] = 1
>>> ddx.a.a = 'a'
>>> ddx
{'a': {'a': 'a'}, 1: {1: 1}}
'''
def __getitem__(self, name):
if name not in self:
return self.setdefault(name, dotdict2())
return dotdict.__getitem__(self, name)
__getattr__ = __getitem__
class dotdict3(dotdict):
'''dotdict 的扩展,支持名称中含 .
>>> ddx = dotdict3()
>>> ddx['a.b.c'] = 'abc'
>>> ddx
{'a': {'b': {'c': 'abc'}}}
>>> ddx['a.b']
{'c': 'abc'}
'''
def __getitem__(self, name):
if isinstance(name, basestring) and '.' in name:
pathes = name.split('.')
name = pathes.pop(-1)
for path in pathes:
self = self[path]
if name not in self:
return self.setdefault(name, dotdict2())
return dotdict.__getitem__(self, name)
def __setitem__(self, name, value):
if isinstance(name, basestring) and '.' in name:
pathes = name.split('.')
name = pathes.pop(-1)
for path in pathes:
self = self[path]
return dotdict.__setitem__(self, name, value)
__getattr__ = __getitem__
if __name__ == '__main__':
import doctest
doctest.testmod()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment