对于项目中的数据类型,通常读取后都是字典dict类型,这种形式对于后续参数访问不方便,因此希望将字典类型转换为对象类型,直接用点来访问相关的属性参数。
1、使用munch库
munch库优点:
1. 速度快;
2. 适用于递归字典;
3. 当访问中间元素时,仍然能够输出相关信息。
munch是第三方库,需要安装:
pip install munch
示例代码:
from munch import DefaultMunch
dic = {'a': 1, 'b': {'c': 2}, 'd': ["AA", {'BB': "CC"}]}
obj = DefaultMunch.fromDict(dic)
print(obj)
print(obj.b)
print(obj.b.c)
print(obj.d)
print(obj.d[0])
print(obj.d[1].BB)
print(obj.d[1].bb)
运行结果:
2、使用bunch库
专门用于提供对 dict 对象的属性样式访问,并且完全按照 OP 的要求进行操作。
使用bunch库前需要安装:
pip install bunch
注意:bunch库在python3中似乎不兼容,存在问题!
3、自我构建类对象
示例代码:
class DictObj(object):
def __init__(self, d):
for key, value in d.items():
if isinstance(key, (list, tuple)):
setattr(self, key, [DictObj(x) if isinstance(x, dict) else x for x in value])
else:
setattr(self, key, DictObj(value) if isinstance(value, dict) else value)
d = {'a': 1, 'b': {'c': 2}, 'd': ["AA", {'BB': "CC"}]}
x = DictObj(d)
print(x.a)
print(x.b)
print(x.b.c)
print(x.d)
# print(x.d[1].BB) # 目前构造的类数据结构还不能兼容更复杂的类型
# print(x.d[1].bb)
运行结果:
示例代码2: 【构造适用于更加复杂的数据类型的类】
def dict_obj(d):
top = type('new', (object,), d)
seqs = tuple, list, set, frozenset
for key, value in d.items():
if isinstance(value, dict):
setattr(top, key, dict_obj(value))
elif isinstance(value, seqs):
setattr(top, key, type(value)(dict_obj(x) if isinstance(x, dict) else x for x in value))
else:
setattr(top, key, value)
return top
d = {'a': 1, 'b': {'c': 2}, 'd': ["AA", {'BB': "CC"}]}
x = dict_obj(d)
print(x)
print(x.a)
print(x.b)
print(x.b.c)
print(x.d)
print(x.d[1].BB)
# print(x.d[1].bb) # 若访问不存在的属性则报错
运行结果:
示例代码3: 【可以与任何深度的任何序列/字典/值结构一起使用。】【适用于嵌套的数据结构】
class Struct(object):
def __init__(self, data):
for name, value in data.items():
setattr(self, name, self._wrap(value))
def _wrap(self, value):
if isinstance(value, (tuple, list, set, frozenset)):
return type(value)([self._wrap(v) for v in value])
else:
return Struct(value) if isinstance(value, dict) else value
d = {'a': 1, 'b': {'c': 2}, 'd': ["AA", {'BB': "CC"}]}
x = Struct(d)
print(x)
print(x.a)
print(x.b)
print(x.b.c)
print(x.d)
print(x.d[1].BB)
# print(x.d[1].bb) # 若访问不存在的属性则报错
运行结果:
4、对于json数据的处理
可以在一行中将它变成一个对象(而不是字典)。
示例代码:
import json
from collections import namedtuple
dic = '{"a": 1, "b": {"c": 2}, "d": ["AA", {"BB": "CC"}]}'
data = json.loads(dic, object_hook=lambda dic: namedtuple("X", dic.keys())(*dic.values()))
print(data)
print(data.a)
print(data.b)
print(data.b.c)
print(data.d)
print(data.d[1])
print(data.d[1].BB)
# print(data.d[1].bb) # 若访问不存在的属性则报错
运行结果:
示例代码2:
import json
class JsonObject(object):
def __init__(self, d):
self.__dict__ = d
dic = '{"a": 1, "b": {"c": 2}, "d": ["AA", {"BB": "CC"}]}'
data = json.loads(dic, object_hook=JsonObject)
print(data)
print(data.a)
print(data.b)
print(data.b.c)
print(data.d)
print(data.d[1])
print(data.d[1].BB)
# print(data.d[1].bb) # 若访问不存在的属性则报错
运行结果:
import json
class JsonObject(object):
def __init__(self, d):
self.__dict__.update(d)
dic = {"a": 1, "b": {"c": 2}, "d": ["AA", {"BB": "CC"}]}
data = json.loads(json.dumps(dic), object_hook=JsonObject)
print(data)
print(data.a)
print(data.b)
print(data.b.c)
print(data.d)
print(data.d[1])
print(data.d[1].BB)
# print(data.d[1].bb) # 若访问不存在的属性则报错
运行结果: