[類別篇] 將 dict 轉成階層式屬性 - tsungjung411/python-study GitHub Wiki
basic
class AttrDict(dict):
def __init__(self, attr_dict):
self.__dict = attr_dict
def __getattr__(self, name):
return self.__dict[name]
def __repr__(self):
return str(self.__dict)
d = AttrDict({
'A': 'a',
'b': 'B',
'C': AttrDict({
'C1': 'c1',
'C2': 'c2'
})
})
print('d.A:', d.A)
print('d.b:', d.b)
print('d.C:', d.C)
print('d.C.C1:', d.C.C1)
執行結果:
d.A: a
d.b: B
d.C: {'C1': 'c1', 'C2': 'c2'}
d.C.C1: c1
advanced
class Dict(dict):
def __init__(self, init_dict: dict = {}):
self.__dict = {}
for k, v in init_dict.items():
if type(v) == dict:
self.__dict[k] = Dict(v)
else:
self.__dict[k] = v
def __setattr__(self, key, value):
if key == '_Dict__dict':
super().__setattr__(key, value)
else:
self.__dict[key] = value
def __getattr__(self, key):
return self.__dict[key]
def __hasattr__(self, key):
return key in self.__dict
def __setitem__(self, key, value):
self.__dict[key] = value
def __getitem__(self, key):
return self.__dict[key]
def __repr__(self):
return repr(self.__dict)
def copy(self):
new_dict = Dict()
for k, v in self.__dict.items():
if type(v) == Dict:
new_dict[k] = v.copy()
else:
new_dict[k] = v
return new_dict
def get(self, key, default=None):
return self.__dict.get(key, default)
def items(self):
return self.__dict.items()
def keys(self):
return self.__dict.keys()
def update(self, new_dict: dict):
for k, v in new_dict.items():
self.__dict[k] = v
def values(self):
return self.__dict.values()
# note implemented yet
# 'clear', 'fromkeys', 'pop', 'popitem', 'setdefault'
d = {'profile': {'name': {'first_name':'tj\'s', 'last_name': 'tsai'}, 'age': 18}}
b = Dict(d)
print(b)
執行結果:
{'profile': {'name': {'first_name': "tj's", 'last_name': 'tsai'}, 'age': 18}}
final solution
class Dict(dict):
def __init__(self, source = None):
if source is None:
super().__init__()
else:
super().__init__(source)
# convert all sub-dict to sub-Dict
for k, v in self.items():
if type(v) == dict:
self[k] = Dict(v)
def __setattr__(self, key, value):
if type(value) == dict:
self[key] = Dict(value)
else:
self[key] = value
def __getattr__(self, key):
return self[key]
def __dir__(self):
# list the attributes of the dict, and all of its keys
return super().__dir__() + [k for k in self.keys()]
def copy(self):
# implement the deep copy
a_copy = Dict()
for k, v in self.items():
if type(v) == Dict:
# recursively copy
a_copy[k] = v.copy()
else:
a_copy[k] = v
return a_copy