You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何不修改原有__init__方法将JSON解析为Python嵌套自定义类实例

实现方案

方案1:纯标准库实现轻量递归反序列化(无需修改现有类)

该方案完全保留现有类的__init__逻辑,无需引入第三方依赖,核心逻辑是根据类的类型注解递归转换嵌套结构:

from typing import get_type_hints, List, Dict
import json

# 现有类无需任何修改
class C(object):
    def __init__(self, name: str):
        self.name = name

class B(object):
    def __init__(self, name: str, c: Dict[str, C]):
        self.name = name
        self.c = c

class A(object):
    def __init__(self, name: str, b: List[B]):
        self.name = name
        self.b = b

def deserialize(data, target_type):
    # 获取容器类型的原始类型
    origin_type = getattr(target_type, '__origin__', None)
    
    # 处理列表泛型
    if origin_type is list:
        item_type = target_type.__args__[0]
        return [deserialize(item, item_type) for item in data]
    # 处理字典泛型
    elif origin_type is dict:
        key_type, value_type = target_type.__args__
        return {deserialize(k, key_type): deserialize(v, value_type) for k, v in data.items()}
    # 处理自定义类
    elif hasattr(target_type, '__init__'):
        init_type_hints = get_type_hints(target_type.__init__)
        init_kwargs = {}
        for param_name, param_type in init_type_hints.items():
            if param_name == 'return':
                continue
            init_kwargs[param_name] = deserialize(data[param_name], param_type)
        return target_type(**init_kwargs)
    # 基础类型直接返回
    else:
        return data

# 使用示例
# 序列化
test_c = C(name="test_c")
test_b = B(name="test_b", c={"c1": test_c})
test_a = A(name="test_a", b=[test_b])
dump = json.dumps(test_a, default=lambda o: o.__dict__)

# 反序列化
load_data = json.loads(dump)
object_a = deserialize(load_data, A)

# 类型校验结果
print(type(object_a)) # <class '__main__.A'> 符合预期
print(type(object_a.b)) # <class 'list'> 符合预期
print(type(object_a.b[0])) # <class '__main__.B'> 符合预期
print(type(object_a.b[0].c["c1"])) # <class '__main__.C'> 符合预期

方案2:第三方库实现(适合复杂嵌套场景)

如果嵌套结构非常复杂,可借助pydantic库简化实现,仅需给现有类加装饰器,原有__init__逻辑完全保留:

from pydantic.dataclasses import dataclass
from typing import List, Dict
import json

@dataclass
class C(object):
    def __init__(self, name: str):
        self.name = name

@dataclass
class B(object):
    def __init__(self, name: str, c: Dict[str, C]):
        self.name = name
        self.c = c

@dataclass
class A(object):
    def __init__(self, name: str, b: List[B]):
        self.name = name
        self.b = b

# 反序列化直接调用即可
load_data = json.loads(dump)
object_a = A(**load_data)

内容的提问来源于stack exchange,提问作者IgorZ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 02:27:02