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

Python存储自定义对象构成的字典的最优方法是什么?

报错原因

你遇到的cannot pickle 'weakref' object错误,本质是Trainer实例中隐含了来自Discord SDK的不可序列化弱引用对象:你在初始化Trainer时传入的user是Discord SDK返回的对象,即使你看起来只取了三个基础属性,要么是你不小心把整个user对象绑定到了Trainer实例上,要么是部分Discord对象的属性本身携带了无法被pickle识别的弱引用标记。

最优存储方案

推荐你使用JSON序列化方案,相比修复pickle问题,JSON方案可读性更高、不受类结构迭代影响、不存在序列化安全风险,适配你的轻量本地存储需求,实现步骤如下:

第一步:给两个自定义类增加序列化/反序列化方法

import json

class Character:
    def __init__(self, slot, name, skills, item=None):
        self.slot = slot # int
        self.name = name # str
        self.skills = skills # 字符串组成的字典
        self.item = item # str
    
    def to_dict(self):
        return {
            "slot": self.slot,
            "name": self.name,
            "skills": self.skills,
            "item": self.item
        }
    
    @classmethod
    def from_dict(cls, data):
        return cls(**data)

class Trainer:
    # 优化初始化逻辑,不要直接传入Discord的user对象,只传需要的基础属性,从根源避免引入不可序列化对象
    def __init__(self, user_id, name, icon):
        self.id = user_id # int
        self.name = name # str
        self.icon = icon # 图片url字符串
        self.team = [] # Character实例组成的列表
    
    def to_dict(self):
        return {
            "id": self.id,
            "name": self.name,
            "icon": self.icon,
            "team": [char.to_dict() for char in self.team]
        }
    
    @classmethod
    def from_dict(cls, data):
        trainer = cls(
            user_id=data["id"],
            name=data["name"],
            icon=data["icon"]
        )
        trainer.team = [Character.from_dict(char_data) for char_data in data["team"]]
        return trainer

注:实例化Trainer时单独取出user.id/user.name/user.icon三个基础值传入即可,彻底规避弱引用问题

第二步:实现master字典的存储和读取

存储代码

# 序列化master字典为可JSON存储的结构
serializable_master = {
    str(user_id): trainer.to_dict() for user_id, trainer in master.items()
}
with open("master.json", "w", encoding="utf-8") as f:
    json.dump(serializable_master, f, ensure_ascii=False, indent=2)

读取代码

with open("master.json", "r", encoding="utf-8") as f:
    serializable_master = json.load(f)
# 反序列化为原对象结构
master = {
    int(user_id): Trainer.from_dict(trainer_data) for user_id, trainer_data in serializable_master.items()
}

如果一定要用pickle方案,只需要按照上面的优化方式修改Trainer的初始化逻辑,不要在实例中留存任何Discord SDK返回的对象引用,就能解决弱引用无法序列化的问题,但依然更推荐JSON方案,更适合你的轻量本地存储场景。

内容的提问来源于stack exchange,提问作者Roopesh-J

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 09:36:03