class EasyDict(dict): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._convert_nested() def _convert_nested(self): for key, value in self.items(): if isinstance(value, dict): self[key] = EasyDict(value) elif isinstance(value, list): self[key] = [EasyDict(item) if isinstance(item, dict) else item for item in value] def __getattr__(self, key): try: return self[key] except KeyError: raise AttributeError(f"'EasyDict' object has no attribute '{key}'") def update(self, **kwargs): assert kwargs is not None and kwargs.get("dict", None) is not None for key, value in kwargs["dict"].items(): cur_value = self.get(key, None) if isinstance(cur_value, dict) and isinstance(value, dict): self[key].update(dict = value) continue if isinstance(cur_value, list) and isinstance(value, list): self[key].extend([EasyDict(item) if isinstance(item, dict) else item for item in value]) continue if isinstance(value, dict): self[key] = EasyDict(value) continue if isinstance(value, list): self[key] = [EasyDict(item) if isinstance(item, dict) else item for item in value] continue self[key] = value def to_dict(self): result = {} for key, value in self.__dict__.items(): if isinstance(value, EasyDict): result[key] = value.to_dict() elif isinstance(value, list): result[key] = [ item.to_dict() if isinstance(item, EasyDict) else item for item in value ] else: result[key] = value return result def test_easy_dict(): easy_dict = EasyDict({"c": 2, "2": 3}) easy_dict.update(dict = {"c": 4, "2": {"d": 5}}) print(easy_dict) if __name__ == '__main__': test_easy_dict()