Skip to content

Instantly share code, notes, and snippets.

@somarlyonks
Last active March 22, 2019 02:22
Show Gist options
  • Select an option

  • Save somarlyonks/e725dee81b2be0a5931738fed34c1a77 to your computer and use it in GitHub Desktop.

Select an option

Save somarlyonks/e725dee81b2be0a5931738fed34c1a77 to your computer and use it in GitHub Desktop.
A delicate proxy to json dicts to read/edit them by ".".
class DotDict(dict):
def __init__(self, value):
self.__dict__['__value'] = value
dict.__init__(self, value)
def __getattr__(self, key):
if key == '__value' or key == '_DotDict__value':
return self.__dict__['__value']
def typer(candidate):
if isinstance(candidate, dict):
return DotDict(candidate)
if isinstance(candidate, str):
return candidate
try:
return [typer(item) for item in candidate]
except TypeError:
return candidate
return candidate
return typer(dict.get(self, key))
def __setattr__(self, key, value):
self[key] = value
self.__value[key] = value
__delattr__ = dict.__delitem__
def __repr__(self):
return dict.__repr__(self.__value)
def get(self, key, default=None):
try:
return self.__getattr__(key)
except TypeError:
return default
except IndexError:
raise IndexError('DotDict index out of range')
@somarlyonks
Copy link
Author

>>> d = {'x': {'y': [1]}, 'z': 2}
>>> m = DotDict(d)
>>> m
{'x': {'y': [1]}, 'z': 2}
>>> x = m.x
>>> x
{'y': [1]}

setting value also changes the source dict

>>> x.y = 1
>>> x
{'y': 1}
>>> m
{'x': {'y': 1}, 'z': 2}
>>> d
{'x': {'y': 1}, 'z': 2}

WARNNINGS:

  • all iterbale will be treated as list(except str)
  • you can not edit mutable object inside it
  • not tried on huge json dicts
>>> x.y[0] = 2
>>> x
{'y': [1]}

you can only assign it by x.y = [2]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment