python内置的json序列化不能自动将对象序列化,必须写encoder才能将其序列化,反序列化也是。所以我写了一个通用的序列化方案,在序列化时将类的信息也保存进去,反序列化时则自动将通过类的初始化创建对象。
注意反序列化时,对象的构造函数必须包含全部的序列化属性
序列化
serializable = (list, str, dict, int, bool, float, set, tuple)
def obj2dict(obj):
if type(obj) in serializable:
if type(obj) in (list, set, tuple):
return [obj2dict(o) for o in obj]
elif isinstance(obj, (dict,)):
return {k: obj2dict(v) for k, v in obj.items()}
else:
return obj
else:
if isinstance(obj, (list, set, tuple)):
return dict(
type=type(obj).__name__,
values=[obj2dict(x) for x in obj]
)
dic: dict[str, Any] = dict()
if hasattr(obj, "skip_attr"):
skip = getattr(obj, "skip_attr")
else:
skip = ()
for attr in obj.__dict__:
if attr not in skip:
dic[attr] = obj2dict(getattr(obj, attr))
return dict(
type=type(obj).__name__,
values=dic
)
反序列化
def dict2obj(obj):
if isinstance(obj, dict):
if "type" in obj and "values" in obj:
for module in modules.values():
if hasattr(module, obj["type"]):
ty = getattr(module, obj["type"])
if isinstance(obj["values"], dict):
obj["values"] = dict2obj(obj["values"])
return ty(**obj["values"])
elif isinstance(obj["values"], (list, set)):
return ty(*[dict2obj(x) for x in obj["values"]])
else:
for k, v in obj.items():
obj[k] = dict2obj(v)
return obj
return obj
elif isinstance(obj, (list, set, tuple)):
for o in obj:
o = dict2obj(o)
return obj
else:
return obj
使用方式
a = student("a", 1)
a_str = json.dumps(obj2dict(a))
b_dict = json.loads(a_str)
b = dict2obj(b_dict)
print(b.name)