Python中使用JSON

Python处理JSON数据,原有的JSON不支持别名,扩展一下

from dataclasses import asdict, is_dataclass
from enum import Enum
import json
from datetime import datetime
from typing import TypeVar, Type, Optional, Any

from model.ConstInfo import ConstInfo

T = TypeVar('T')


class JsonUtil:

    @staticmethod
    def to_json(obj: object) -> Optional[str]:
        """对象转JSON字符串
        :param obj:需要序列化的对象
        :return: JSON字符串(失败返回None)
        """

        try:
            if hasattr(obj, 'to_dict'):
                data = obj.to_dict()
            else:
                data = obj.__dict__

            return json.dumps(data,
                              default=JsonUtil._serialize,
                              ensure_ascii=False)
        except Exception as e:
            print(e)
            return None

    @staticmethod
    def parse_json(json_str: str, obj_type: Type[T]) -> Optional[T]:
        """Json字符串解析
        :param json_str: Json字符串
        :param obj_type: 解析对象类型
        :return: 解析对象
        """
        try:
            raw_data: dict[str, Any] = json.loads(json_str)

            if hasattr(obj_type, 'from_dict'):
                return obj_type.from_dict(raw_data)

            #  处理普通类
            init_data = {
                key.replace(' ', '_'): value
                for key, value in raw_data.items()
            }
            return obj_type(**init_data)
        except Exception as e:
            print(e)
            return None

    @staticmethod
    def _serialize(o: Any) -> Any:
        """自定义序列化逻辑"""
        # 处理datetime
        if isinstance(o, datetime):
            return o.strftime('%Y-%m-%d %H:%M:%S')
        # 处理枚举类型
        if isinstance(o, Enum):
            return o.value
        # 处理dataclass对象
        if is_dataclass(o):
            return asdict(o)
        # 处理自定义to_dict方法的对象
        if hasattr(o, 'to_dict'):
            return o.to_dict()
        # 其他对象尝试使用 __dict__
        if hasattr(o, '__dict__'):
            return vars(o)
        # 兜底处理
        return str(o)

处理JSON映射:

from dataclasses import dataclass, asdict, fields, is_dataclass
from typing import Any, Dict, Type, get_args, get_type_hints


def field_mapper(mapping: Dict[str, str]):

    def decorator(cls):
        # 序列化逻辑
        def to_dict(self):
            # 递归处理嵌套对象
            def _convert(value):
                if hasattr(value, 'to_dict'):
                    return value.to_dict()
                elif isinstance(value, list):
                    return [_convert(v) for v in value]
                elif isinstance(value, dict):
                    return {k: _convert(v) for k, v in value.items()}
                else:
                    return value

            # 获取原始数据并递归转换
            raw_data = {
                field.name: getattr(self, field.name)
                for field in fields(self)
            }
            converted_data = {k: _convert(v) for k, v in raw_data.items()}

            # 应用字段名映射
            return {mapping.get(k, k): v for k, v in converted_data.items()}
            """这是一段字典推导式结构:{key_expression:value_expression for item in iterable}
            for k,v in data.items():遍历字典
            mapping.get(k, k):如果字典中存在k,则返回对应的值,否则返回k本身            
            """

        # 反序列化逻辑
        @classmethod
        def from_dict(cls, data: Dict[str, Any]):
            reverse_mapping = {v: k for k, v in mapping.items()}
            remapped_data = {}
            for json_key, value in data.items():
                # 反向映射字段名
                cls_key = reverse_mapping.get(json_key, json_key)
                # 获取字段类型提示
                field_type = get_type_hints(cls).get(cls_key, Any)
                # 递归处理嵌套对象
                remapped_data[cls_key] = _convert_value(value, field_type)
            return cls(**remapped_data)

        def _convert_value(value: Any, target_type: Type):
            # 处理嵌套对象(如 RuleInfo)
            if is_dataclass(target_type) and hasattr(
                    target_type, 'from_dict') and isinstance(value, dict):
                return target_type.from_dict(value)
            # 处理列表中的对象(如 List[RuleInfo])
            elif isinstance(value, list):
                # 获取列表元素的类型(例如 List[RuleInfo] -> RuleInfo)
                item_type = get_args(target_type)[0] if get_args(
                    target_type) else Any
                return [_convert_value(item, item_type) for item in value]
            # 其他类型直接返回
            else:
                return value

        cls.to_dict = to_dict
        cls.from_dict = from_dict
        return cls

    return decorator
posted @ 2025-03-11 14:27  破落户儿  阅读(44)  评论(0)    收藏  举报