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

Python中Meal对象无法JSON序列化问题求助

解决自定义Meal类的JSON序列化问题

你遇到的错误是因为Python的json模块默认只能序列化内置数据类型(如字典、列表、字符串等),而你的Meal是自定义类的实例,json.dump无法直接识别这类对象,所以抛出了序列化失败的异常。

下面给你两种可行的修复方案,同时兼顾保存和加载的完整流程(原代码的load方法也有问题,加载后会得到字典而非Meal实例,需要一并修正):

方案一:给Meal类添加序列化/反序列化方法

这种方法最直观,通过给Meal类添加转字典和从字典创建实例的方法,手动处理对象与JSON格式的转换:

修改Meal类

class Meal:
    def __init__(self, name, ingredients):
        self.name = name
        self.ingredients = ingredients
    
    # 将Meal实例转为字典,用于序列化
    def to_dict(self):
        return {
            "name": self.name,
            "ingredients": self.ingredients
        }
    
    # 从字典创建Meal实例,用于反序列化
    @classmethod
    def from_dict(cls, meal_dict):
        return cls(meal_dict["name"], meal_dict["ingredients"])

修改MealPlan的save和load方法

def save(self, filename):
    # 遍历所有餐食,把Meal实例转为字典
    serialized_meals = {}
    for day, meals in self.meals.items():
        serialized_meals[day] = [meal.to_dict() for meal in meals]
    
    data = {"days": self.days, "meals": serialized_meals}
    with open(filename, "w") as f:
        json.dump(data, f, indent=4)  # indent参数可让JSON格式更美观,可选

def load(self, filename):
    with open(filename, "r") as f:
        data = json.load(f)
    
    self.days = data["days"]
    # 把字典转回Meal实例
    self.meals = {}
    for day, meal_dicts in data["meals"].items():
        self.meals[day] = [Meal.from_dict(meal_dict) for meal_dict in meal_dicts]

方案二:自定义JSON编码器

如果不想修改Meal类的结构,可以自定义一个JSON编码器,告诉json模块如何处理Meal对象:

定义自定义编码器

class MealEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, Meal):
            # 返回Meal对象的字典表示,添加类型标记方便反序列化
            return {
                "__type__": "Meal",
                "name": obj.name,
                "ingredients": obj.ingredients
            }
        # 其他类型交给默认编码器处理
        return super().default(obj)

修改MealPlan的save和load方法

def save(self, filename):
    data = {"days": self.days, "meals": self.meals}
    with open(filename, "w") as f:
        json.dump(data, f, cls=MealEncoder, indent=4)

def load(self, filename):
    # 自定义反序列化钩子,识别标记并转回Meal实例
    def decode_meal(obj):
        if "__type__" in obj and obj["__type__"] == "Meal":
            return Meal(obj["name"], obj["ingredients"])
        return obj
    
    with open(filename, "r") as f:
        data = json.load(f, object_hook=decode_meal)
    
    self.days = data["days"]
    self.meals = data["meals"]

两种方案都能解决你的问题:方案一适合结构简单的自定义类,代码可读性高;方案二更灵活,无需修改原类结构。修改后运行代码,save和load操作都能正常执行,加载后的meal plan里会是正确的Meal实例,而非字典。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 08:10:28