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
相关产品推荐
相关产品推荐

