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

为Identity类添加classmethod后JSON序列化报错的排查与解决

问题根源

你写的to_json是类方法,里面传给json.dumps的是cls(即Identity类本身),但你的BasicEncoder原本是用来序列化类的实例对象的。类本身的__dict__是mappingproxy类型(存储类属性的只读映射),不是实例的普通字典,所以会抛出'mappingproxy' object has no attribute '__dict__'错误。另外,序列化类时会遍历类级别的成员(比如类方法、属性描述符),这就导致了'getset_descriptor' object has no attribute '__dict__'这类异常。

解决方案

方案1:将to_json改为实例方法(最直接)

把类方法改成实例方法,操作当前实例而非类本身,同时优化编码器,只处理Identity实例:

from __future__ import annotations
import json
from typing import Any

class Identity:
    def __init__(self, name: str) -> None:
        self.name = name
        self.permissions = []

    # 改成实例方法,操作self(当前实例)
    def to_json(self) -> str:
        return json.dumps(self, cls=BasicEncoder)

class BasicEncoder(json.JSONEncoder):
    def default(self, obj: Any) -> Any:
        # 只处理Identity实例,避免其他类型误操作
        if isinstance(obj, Identity):
            return {
                "name": obj.name,
                "permissions": obj.permissions
            }
        # 其他类型交给父类处理
        return super().default(obj)
    
id = Identity(name='Random name')
print(id.to_json())

方案2:保留类方法,但传入实例参数

如果一定要用类方法,需要让方法接收要序列化的实例作为参数:

from __future__ import annotations
import json
from typing import Any

class Identity:
    def __init__(self, name: str) -> None:
        self.name = name
        self.permissions = []

    @classmethod
    def to_json(cls, instance: Identity) -> str:
        return json.dumps(instance, cls=BasicEncoder)

class BasicEncoder(json.JSONEncoder):
    def default(self, obj: Any) -> Any:
        if isinstance(obj, Identity):
            return obj.__dict__
        return super().default(obj)
    
id = Identity(name='Random name')
# 调用时传入实例
print(Identity.to_json(id))

方案3:使用dataclass简化序列化(Python 3.7+)

用dataclass可以省去手动处理__dict__的麻烦,借助asdict快速转换为可序列化的字典:

from __future__ import annotations
import json
from dataclasses import dataclass, asdict

@dataclass
class Identity:
    name: str
    permissions: list = None
    
    # 初始化默认空列表
    def __post_init__(self):
        if self.permissions is None:
            self.permissions = []
    
    def to_json(self) -> str:
        return json.dumps(asdict(self))

id = Identity(name='Random name')
print(id.to_json())

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 13:19:52