Python 仿fastjson的序列化和反序列化


目前正则学习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))
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值