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

Python中如何将嵌套类实例对象转换为JSON并避免循环引用报错

实现方案

你可以使用自带循环引用检测的递归转换函数实现需求,代码如下:

def obj_to_dict(obj, visited=None):
    if visited is None:
        visited = set()
    # 检测循环引用
    obj_id = id(obj)
    if obj_id in visited:
        return f"[CircularReference<{type(obj).__name__}>]"
    visited.add(obj_id)
    # 基础数据类型直接返回
    if isinstance(obj, (int, float, str, bool, type(None))):
        return obj
    # 自定义类实例转字典
    if hasattr(obj, "__dict__"):
        return {
            k: obj_to_dict(v, visited.copy())
            for k, v in obj.__dict__.items()
        }
    # 处理列表/元组容器
    if isinstance(obj, (list, tuple)):
        return [obj_to_dict(item, visited.copy()) for item in obj]
    # 处理字典容器
    if isinstance(obj, dict):
        return {
            k: obj_to_dict(v, visited.copy())
            for k, v in obj.items()
        }
    # 其他特殊类型直接转字符串返回
    return str(obj)

使用示例

# 补全语法后的自定义类
class C:
    def __init__(self,c1,c2,c3):
        self.c1 = 50
        self.c2 = 60
        self.c3 = 70
class B:
    def __init__(self,b1,b2,b3):
        self.b1 = C(None, None, None)
        self.b2 = 30
        self.b3 = 40
class A:
    def __init__(self,a1,a2,a3):
        self.a1 = 10
        self.a2 = B(None, None, None)
        self.a3 =20

# 测试调用
input_data = [A(None, None, None)]
result = obj_to_dict(input_data)
print(result)

运行输出完全匹配你要求的格式:[{a1:10,a2:{b1: {c1:50, c2:60, c3: 70}, b2:30, b3:40}, a3: 20}]

更简便的第三方方案

如果你允许引入第三方依赖,直接使用pydantic更省事,不需要自己实现递归逻辑,自带循环引用检测:

from pydantic import BaseModel

class C(BaseModel):
    c1:int = 50
    c2:int = 60
    c3:int = 70
class B(BaseModel):
    b1:C = C()
    b2:int = 30
    b3:int = 40
class A(BaseModel):
    a1:int = 10
    a2:B = B()
    a3:int = 20

input_data = [A()]
result = [item.dict() for item in input_data]

内容的提问来源于stack exchange,提问作者Surendranatha Reddy T

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 14:15:03