-
Python Code for Dictionary Dot Accessible & Nested Key Handlingcomputer science 2023. 6. 24. 14:30반응형
In Python, dictionaries are a versatile data structure that allows us to store key-value pairs. However, they might not always be convenient to use, especially when we're dealing with nested structures and we'd prefer to access them using dot notation, much like we would with an object's attributes. So, today, we're going to create a Python class that allows for dot-accessible dictionary keys and automatic nested key handling.
반응형Class Creation
The core of our solution is to create a Python class that inherits from the dict class, and override certain magic methods to change the behavior of our dictionary. We'll call our class DotAccessibleDict.
dot_dict.py
import json class DotAccessibleDict(dict): """ A dictionary that allows dot notation to access keys. also it allows to access and generate nested structure. ex) data = DotAccessibleDict() data.new_key.generate_test.nested_key = 1 functions: get("key", default) : returns the value for key if key is in the dictionary, else default dict() : returns a dict object json() : returns a json string """ def __init__(self, *args, **kwargs): super(DotAccessibleDict, self).__init__(*args, **kwargs) for arg in args: if isinstance(arg, dict): for k, v in arg.items(): self[k] = v if kwargs: for k, v in kwargs.items(): self[k] = v def __getattr__(self, attr): if attr in self: return self[attr] else: self[attr] = type(self)() return self[attr] def __setattr__(self, key, value): if isinstance(value, dict): self[key] = type(self)(value) else: self[key] = value def __setitem__(self, key, value): if isinstance(value, dict): super(DotAccessibleDict, self).__setitem__(key, type(self)(value)) else: super(DotAccessibleDict, self).__setitem__(key, value) def __delattr__(self, attr): try: del self[attr] except KeyError: raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{attr}'") def get(self, key, default=None): if key in self: return super().get(key, default) else: return default def dict(self): result = {} for key, value in self.items(): if isinstance(value, DotAccessibleDict): result[key] = value.dict() else: result[key] = value return result def json(self): return json.dumps(self.dict(), ensure_ascii=False)
Explanation
This class works by creating a new instance of itself every time a non-existent attribute is accessed. This means that we can keep chaining attribute accesses and create deeply nested structures with ease.
Moreover, when setting a value, if the value is a dictionary, we convert it to an instance of DotAccessibleDict. This ensures that nested dictionaries also support dot-accessible keys.
We also override the __setitem__ method to ensure that nested dictionaries are converted to DotAccessibleDict instances when set using index notation.
Finally, we implement dict() and json() methods that return a regular dictionary and a JSON string representation of our dictionary, respectively. The dict() method works by recursively converting all DotAccessibleDict instances to regular dictionaries.반응형Example
test.py
from dot_dict import DotAccessibleDict ## test code if __name__ == "__main__": data = DotAccessibleDict() data.newkey.first = 1 print(data) # {'newkey': {'first': 1}} print(data.newkey.first) # 1 data.newkey.second = {"issue":{"message":"blahblah", "code":9}} print(data) # {'newkey': {'first': 1, 'second': {'issue': {'message': 'blahblah', 'code': 9}}}} print(data.newkey.second.issue.message) # 'blahblah' print(f"to dict --> {data.dict()}") print(f"to json --> {data.json()}")
반응형'computer science' 카테고리의 다른 글
Triton server memory leak (메모리 릭) malloc설정을 바꿔보자 (0) 2024.05.13 ChatGPT + Code Interpreter 세팅 & 시각화 잘하려면 알아야 할 5가지! (0) 2023.07.16 앞으로는 FastAPI를 Uvicorn + Gunicorn 쌍두마차로 활용하자 (0) 2023.06.27 FastAPI에서 Redis를 비동기로 사용하도록 설정하기 (0) 2023.06.17