目前正则学习Python,学习么,总是要写点什么来增强记忆的.
当视频看到json相关的,看着教程里json的处理方式,就想着对象是怎么序列化和反序列化的.
然后后来看到面向对象结合json的处理案例,当时感觉这json反序列化的方式好违和,还要手写反序列化的实现.
然后去网上各种搜,没搜到一个简单的工具类,于是就想着仿照fastjson自己写写看
目前只简单的实现了toJSONString、parseObject、parseList.
PS1:值为None的属性不会被序列化
PS2:类中的属性必须进行类型申明(这个行为在Python似乎叫注解,感觉怪怪的)
PS3:并没有经过详细测试,不能保证是否靠谱
工具类
import json
from builtins import isinstance
from typing import TypeVar,Type,get_type_hints
T = TypeVar('T')
def toJSONString(obj)->str:
return json.dumps(__toJSONString(obj),ensure_ascii=False)
def __toJSONString(obj):
if isinstance(obj, list):
json_array = []
for o in obj:
if isinstance(o, list):
json_array.append(__toJSONString(o))
elif isinstance(o, int) or isinstance(o, float) or isinstance(o, str) or isinstance(o, bool) or isinstance(o, type(None)) or isinstance(o, dict):
json_array.append(o)
else:
json_array.append(__toJSONString(o))
return json_array
elif isinstance(obj, object):
attrs = vars(obj)
json_obj = {}
for attr in attrs:
value=getattr(obj, attr)
if isinstance(value, list):
json_obj[attr] = __toJSONString(value)
elif isinstance(value, int) or isinstance(value, float) or isinstance(value, str) or isinstance(value, bool) or isinstance(value, type(None)) or isinstance(value, dict):
json_obj[attr] = value
else :
json_obj[attr] = __toJSONString(value)
return json_obj
else:
return obj
def parseObject(json_obj_str:str, clazz:Type[T]) -> T:
json_obj=json.loads(json_obj_str)
return __parseObject(json_obj,clazz)
def __parseObject(json_obj, clazz:Type[T]) -> T:
all_attrs = __allAttrs(clazz)
if isinstance(json_obj, dict):
a = clazz()
# 获取当前对象所有属性及对应属性声明的类型
all_class_type_hints = get_type_hints(a)
for attr in all_attrs:
if attr in json_obj:
if isinstance(json_obj[attr], list):
#如果没有申明类型,则直接赋值
if all_class_type_hints.__contains__(attr):
#如果申明了类型,则解析list
try:
#获取list中的泛型
list_t = all_class_type_hints[attr].__args__[0]
except:
list_t = None
#如果获取不到list中的泛型,则直接赋值
if (list_t != None):
setattr(a, attr, __parseList(json_obj[attr], list_t))
else:
setattr(a, attr, json_obj[attr])
else:
setattr(a, attr, json_obj[attr])
elif isinstance(json_obj[attr], dict):
if all_class_type_hints.__contains__(attr):
setattr(a, attr, __parseObject(json_obj[attr], all_class_type_hints[attr]))
else:
setattr(a, attr, json_obj[attr])
else:
setattr(a, attr, json_obj[attr])
return a
else:
return json_obj
def parseList(json_array_str:str, clazz:Type[T]) -> list[T]:
json_array=json.loads(json_array_str)
return __parseList(json_array,clazz)
def __parseList(json_array, clazz:Type[T]) -> list[T]:
all_attrs=__allAttrs(clazz)
alist = []
for json_obj in json_array:
if isinstance(json_obj, dict):
a = clazz()
# 获取当前对象所有属性及对应属性声明的类型
all_class_type_hints = get_type_hints(a)
for attr in all_attrs:
if attr in json_obj:
if isinstance(json_obj[attr],list):
# 如果没有申明类型,则直接赋值
if all_class_type_hints.__contains__(attr):
# 如果申明了类型,则解析list
try:
# 获取list中的泛型
list_t=all_class_type_hints[attr].__args__[0]
except:
list_t=None
# 如果获取不到list中的泛型,则直接赋值
if(list_t != None):
setattr(a, attr, __parseList(json_obj[attr], list_t))
else:
setattr(a, attr, json_obj[attr])
else:
setattr(a, attr,json_obj[attr])
elif isinstance(json_obj[attr], dict):
if all_class_type_hints.__contains__(attr):
setattr(a,attr,__parseObject(json_obj[attr], all_class_type_hints[attr]))
else:
setattr(a, attr,json_obj[attr])
else:
setattr(a, attr, json_obj[attr])
alist.append(a)
else:
alist.append(json_obj)
return alist
def __allAttrs(clazz:Type[T]) -> list[str]:
all_attrs = []
attrs = vars(clazz)
for attr in attrs:
if not (attr.startswith("__") and attr.endswith("__")):
all_attrs.append(attr)
a = clazz()
try:
objAttrs = vars(a)
except:
return all_attrs
for attr in objAttrs:
if (not (attr.startswith("__") and attr.endswith("__"))) and attr not in all_attrs:
all_attrs.append(attr)
parent_class_list = a.__class__.__bases__
for parent_class in parent_class_list:
sub_all_attrs=__allAttrs(parent_class)
for attr in sub_all_attrs:
if attr not in all_attrs:
all_attrs.append(attr)
return all_attrs
示例
class d:
age: int = None
def __init__(self):
self.gg=None
pass
class c():
id:int = None
name:str = None
def __init__(self):
pass
class b():
id:int = None
name:str = None
c_list:list[c] = None
def __init__(self):
pass
class a(d):
id:int = None
name:str = None
b_obj:b = None
t_list:list[int] = None
def __init__(self):
super().__init__()
pass
if __name__ == '__main__':
json_str='[{"id":1,"name":"张三","b_obj":{"id":2,"c_list":[{"name":"ssss"}]},"t_list":[1,2,3],"age":111,"gg":"abv"}]'
aobj=parseList(json_str,a)
print(aobj[0].b_obj.c_list[0].name)
print(toJSONString(aobj))