Python Accessing Dict Items through Dot
All lines below will show the result which you expect.
#types/__init__.py
from typing import Iterable
class adict(dict):
__getattr__ = dict.__getitem__
__setattr__ = dict.__setitem__
__delattr__ = dict.__delitem__
@staticmethod
def _convert(obj):
if not isinstance(obj, Iterable):
raise RecursionError(f"{obj} is not {Iterable}")
if hasattr(obj, "items"):
for k, v in obj.items():
if isinstance(v, dict):
obj[k] = adict(v)
return obj
def __init__(self, *args, **kwargs):
_args = (self._convert(args[0]),)
super().__init__(*_args, **kwargs)
def update(self, E=None, **kwargs):
super().update(adict(E))
def trav_d(obj):
print(f"Traverse {obj}")
def _trav(obj):
print(type(obj), obj)
if hasattr(obj, "items"):
for k, v in obj.items():
print(f"{v} is {type(v)}")
if isinstance(v, Iterable) and not isinstance(v, list):
_trav(v)
_trav(obj)
__all__ = [adict, trav_d]
Loading json with this custom dictionary.
이거 하려고 metaclass 까지 찾고 헛고생을 했지만, 문득 json의 소스코드를 봐볼까 ? 라는 생각이 들었고, 모든게 해결되었다. json 소스코드를 깊게 알 필요는 없고 딱 parameter만 보면 감이 잡힌다. 사실 json.load()
쓰면서 그냥 파일포인터 넣을 생각만 하고있었는데, object_hook
이 있는게 아닌가. 사실.. Documentation 보는 습관이 없어서 생긴 문제다…. 기르도록 하자.
사용법은 이곳
with open(filepath, 'r') as f:
_data = json.load(f, object_hook= lambda d: adict(d))
return _data
Json으로 로드할때 nested는 죽어도 끝까지 dict로만 되던 것이 위 방법으로써 해결됐다.