class DotDictionary(dict):
def __init__(self, init_value=None):
if not init_value:
init_value = {}
super(DotDictionary, self).__init__()
if not isinstance(init_value, dict):
raise TypeError('Expected dict, got {}'.format(type(init_value)))
self._dict_to_self(init_value)
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 __getstate__(self):
return self
def __setstate__(self, state):
self = state
def __repr__(self):
return super(DotDictionary, self).__repr__()
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)
Y2xhc3MgRG90RGljdGlvbmFyeShkaWN0KToKCiAgICBkZWYgX19pbml0X18oc2VsZiwgaW5pdF92YWx1ZT1Ob25lKToKCiAgICAgICAgaWYgbm90IGluaXRfdmFsdWU6CiAgICAgICAgICAgIGluaXRfdmFsdWUgPSB7fQoKICAgICAgICBzdXBlcihEb3REaWN0aW9uYXJ5LCBzZWxmKS5fX2luaXRfXygpCiAgICAgICAgaWYgbm90IGlzaW5zdGFuY2UoaW5pdF92YWx1ZSwgZGljdCk6CiAgICAgICAgICAgIHJhaXNlIFR5cGVFcnJvcignRXhwZWN0ZWQgZGljdCwgZ290IHt9Jy5mb3JtYXQodHlwZShpbml0X3ZhbHVlKSkpCgogICAgICAgIHNlbGYuX2RpY3RfdG9fc2VsZihpbml0X3ZhbHVlKQoKICAgIGRlZiBfX2dldGF0dHJfXyhzZWxmLCBuYW1lKToKICAgICAgICByZXR1cm4gc2VsZltuYW1lXQoKICAgIGRlZiBfX3NldGF0dHJfXyhzZWxmLCBuYW1lLCB2YWwpOgogICAgICAgIGlmIGlzaW5zdGFuY2UodmFsLCBkaWN0KToKICAgICAgICAgICAgdmFsID0gRG90RGljdGlvbmFyeSh2YWwpCiAgICAgICAgc2VsZltuYW1lXSA9IHZhbAoKICAgIGRlZiBfX3NldGl0ZW1fXyhzZWxmLCBuYW1lLCB2YWwpOgogICAgICAgIGlmIGlzaW5zdGFuY2UodmFsLCBkaWN0KToKICAgICAgICAgICAgdmFsID0gRG90RGljdGlvbmFyeSh2YWwpCgogICAgICAgIHN1cGVyKERvdERpY3Rpb25hcnksIHNlbGYpLl9fc2V0aXRlbV9fKG5hbWUsIHZhbCkKCiAgICBkZWYgX19kZWxhdHRyX18oc2VsZiwgbmFtZSk6CiAgICAgICAgZGVsIHNlbGZbbmFtZV0KCiAgICBkZWYgX19nZXRzdGF0ZV9fKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmCgogICAgZGVmIF9fc2V0c3RhdGVfXyhzZWxmLCBzdGF0ZSk6CiAgICAgICAgc2VsZiA9IHN0YXRlCgogICAgZGVmIF9fcmVwcl9fKHNlbGYpOgogICAgICAgIHJldHVybiBzdXBlcihEb3REaWN0aW9uYXJ5LCBzZWxmKS5fX3JlcHJfXygpCgogICAgZGVmIF9kaWN0X3RvX3NlbGYoc2VsZiwgZGN0KToKICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBkY3QuaXRlbXMoKToKICAgICAgICAgICAgaWYgaXNpbnN0YW5jZSh2YWx1ZSwgKHR1cGxlLCBsaXN0KSk6CiAgICAgICAgICAgICAgICBmb3IgaSwgXyBpbiBlbnVtZXJhdGUodmFsdWUpOgogICAgICAgICAgICAgICAgICAgIGlmIGlzaW5zdGFuY2UodmFsdWVbaV0sIGRpY3QpOgogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZVtpXSA9IERvdERpY3Rpb25hcnkodmFsdWVbaV0pCiAgICAgICAgICAgIHNlbGZba2V5XSA9IHZhbHVlCiAgICAgICAgICAgIAogICAgICAgICAgICAKIApkID0geydhJzogMCwKICAgICAnYic6IHsnYWEnOiAxLCAnYmInOiB7J2FhYSc6IDIsICdiYmInOiAzLCAnY2NjJzogeydhYWFhJzogNH19fSwKICAgICAnYyc6IFs1LCB7J2FhYWFhJzogNiwgJ2JiYmJiJzogNywgJ2NjY2NjJzogW3snYWFhYWFhJzogOH1dfV19CgpkZCA9IERvdERpY3Rpb25hcnkoZCkKZGRbJ2RpY3QnXSA9IHsnaGV5JzogJ2hleSd9CmRkLmRpY3QuaGVsbG8gPSB7J2hlbGxvJzogMTIzfQogCnByaW50KGRkLmEpCnByaW50KGRkLmIuYWEpCnByaW50KGRkLmNbMV0uYWFhYWEpCnByaW50KGRkLmNbMV0uY2NjY2NbMF0uYWFhYWFhKQpwcmludChkZC5kaWN0LmhleSkKcHJpbnQoZGQuZGljdC5oZWxsby5oZWxsbykK