class DotDictionary(dict):
def __init__(self, init_value):
if not isinstance(init_value, dict):
raise TypeError('Expected dict, got {}'.format(type(init_value)))
self._dict_to_self(init_value)
super(DotDictionary, self).__init__()
def __getattr__(self, name):
return self[name]
def __setattr__(self, name, val):
if isinstance(val, dict):
val = DotDictionary(val)
self[name] = val
def __setitem__(self, name, val):
if isinstance(val, dict):
val = DotDictionary(val)
super(DotDictionary, self).__setitem__(name, val)
def __delattr__(self, name):
del self[name]
def _dict_to_self(self, dct):
for key, value in dct.items():
if isinstance(value, (tuple, list)):
for i, _ in enumerate(value):
if isinstance(value[i], dict):
value[i] = DotDictionary(value[i])
self[key] = value
d = {'a': 0,
'b': {'aa': 1, 'bb': {'aaa': 2, 'bbb': 3, 'ccc': {'aaaa': 4}}},
'c': [5, {'aaaaa': 6, 'bbbbb': 7, 'ccccc': [{'aaaaaa': 8}]}]}
dd = DotDictionary(d)
dd['dict'] = {'hey': 'hey'}
dd.dict.hello = {'hello': 123}
print(dd.a)
print(dd.b.aa)
print(dd.c[1].aaaaa)
print(dd.c[1].ccccc[0].aaaaaa)
print(dd.dict.hey)
print(dd.dict.hello.hello)
Y2xhc3MgRG90RGljdGlvbmFyeShkaWN0KToKCiAgICBkZWYgX19pbml0X18oc2VsZiwgaW5pdF92YWx1ZSk6CiAgICAgICAgaWYgbm90IGlzaW5zdGFuY2UoaW5pdF92YWx1ZSwgZGljdCk6CiAgICAgICAgICAgIHJhaXNlIFR5cGVFcnJvcignRXhwZWN0ZWQgZGljdCwgZ290IHt9Jy5mb3JtYXQodHlwZShpbml0X3ZhbHVlKSkpCgogICAgICAgIHNlbGYuX2RpY3RfdG9fc2VsZihpbml0X3ZhbHVlKQogICAgICAgIHN1cGVyKERvdERpY3Rpb25hcnksIHNlbGYpLl9faW5pdF9fKCkKCiAgICBkZWYgX19nZXRhdHRyX18oc2VsZiwgbmFtZSk6CiAgICAgICAgcmV0dXJuIHNlbGZbbmFtZV0KCiAgICBkZWYgX19zZXRhdHRyX18oc2VsZiwgbmFtZSwgdmFsKToKICAgICAgICBpZiBpc2luc3RhbmNlKHZhbCwgZGljdCk6CiAgICAgICAgICAgIHZhbCA9IERvdERpY3Rpb25hcnkodmFsKQogICAgICAgIHNlbGZbbmFtZV0gPSB2YWwKCiAgICBkZWYgX19zZXRpdGVtX18oc2VsZiwgbmFtZSwgdmFsKToKICAgICAgICBpZiBpc2luc3RhbmNlKHZhbCwgZGljdCk6CiAgICAgICAgICAgIHZhbCA9IERvdERpY3Rpb25hcnkodmFsKQoKICAgICAgICBzdXBlcihEb3REaWN0aW9uYXJ5LCBzZWxmKS5fX3NldGl0ZW1fXyhuYW1lLCB2YWwpCgogICAgZGVmIF9fZGVsYXR0cl9fKHNlbGYsIG5hbWUpOgogICAgICAgIGRlbCBzZWxmW25hbWVdCgogICAgZGVmIF9kaWN0X3RvX3NlbGYoc2VsZiwgZGN0KToKICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBkY3QuaXRlbXMoKToKICAgICAgICAgICAgaWYgaXNpbnN0YW5jZSh2YWx1ZSwgKHR1cGxlLCBsaXN0KSk6CiAgICAgICAgICAgICAgICBmb3IgaSwgXyBpbiBlbnVtZXJhdGUodmFsdWUpOgogICAgICAgICAgICAgICAgICAgIGlmIGlzaW5zdGFuY2UodmFsdWVbaV0sIGRpY3QpOgogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZVtpXSA9IERvdERpY3Rpb25hcnkodmFsdWVbaV0pCiAgICAgICAgICAgIHNlbGZba2V5XSA9IHZhbHVlCgoKZCA9IHsnYSc6IDAsCiAgICAgJ2InOiB7J2FhJzogMSwgJ2JiJzogeydhYWEnOiAyLCAnYmJiJzogMywgJ2NjYyc6IHsnYWFhYSc6IDR9fX0sCiAgICAgJ2MnOiBbNSwgeydhYWFhYSc6IDYsICdiYmJiYic6IDcsICdjY2NjYyc6IFt7J2FhYWFhYSc6IDh9XX1dfQoKZGQgPSBEb3REaWN0aW9uYXJ5KGQpCmRkWydkaWN0J10gPSB7J2hleSc6ICdoZXknfQpkZC5kaWN0LmhlbGxvID0geydoZWxsbyc6IDEyM30KCnByaW50KGRkLmEpCnByaW50KGRkLmIuYWEpCnByaW50KGRkLmNbMV0uYWFhYWEpCnByaW50KGRkLmNbMV0uY2NjY2NbMF0uYWFhYWFhKQpwcmludChkZC5kaWN0LmhleSkKcHJpbnQoZGQuZGljdC5oZWxsby5oZWxsbykK