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

Python中如何序列化嵌套在对象实例内的对象实例列表为JSON格式

Python嵌套自定义类JSON序列化解决方案

问题原因

  • Python标准库json模块默认仅支持序列化字符串、数字、列表、字典、布尔值等原生类型,无法直接序列化自定义类实例
  • 直接访问实例__dict__仅能获取当前类的第一层属性,其中嵌套的Fridge实例列表仍然属于不可直接序列化的自定义类型
  • 先单独序列化单个Restaurant再塞入列表的写法会导致最终JSON结构出现字符串嵌套,不符合预期格式

解决方案

给两个自定义类分别封装to_dict实例方法,递归将自身属性转为可序列化的原生字典结构,完全匹配你预期的输出格式。如果你熟悉JS的话,这个to_dict方法的作用和JS中类的toJSON方法类似,区别是Python的json模块不会自动调用这个方法,需要你手动执行转换。

1. 改造类定义

class Restaurant:
    def __init__(self, owner, password):
        self.__password = password
        self.owner = owner
        self.__owned_fridges = [] # list of owned fridges

    def add_fridge(self):
        nickname = input("What would you like to name the fridge: ")
        # 注意如果之前定义了fr为Fridge的别名可以保留,否则直接用Fridge类名
        self.__owned_fridges.append(Fridge(self.owner, nickname))
        print("Fridge added!")
    
    # 新增序列化方法
    def to_dict(self):
        return {
            "restaurant": {
                "name": self.owner,
                "pw": self.__password,
                "fridges": [fridge.to_dict() for fridge in self.__owned_fridges]
            }
        }
    
    # 可选:反序列化方法,应用重启读取数据时转回可调用方法的实例
    @classmethod
    def from_dict(cls, data):
        rest_data = data["restaurant"]
        instance = cls(rest_data["name"], rest_data["pw"])
        instance._Restaurant__owned_fridges = [Fridge.from_dict(f) for f in rest_data["fridges"]]
        return instance
 

class Fridge:
    def __init__(self, owner, nickname):
        self.nickname = nickname
        self.owner = owner
        self.__authorized_users = [owner]
        self.__contents = []

    def add_to_fridge(self):
        if len(self.__contents) == 5:
            print("Your fridge is full!")
        else:
            item = input("What would you like to add : ")
            self.__contents.append(item)
    
    # 新增序列化方法
    def to_dict(self):
        return {
            "fridge": {
                "owner": self.owner,
                "nickname": self.nickname,
                "contents": self.__contents
            }
        }
    
    # 可选:反序列化方法
    @classmethod
    def from_dict(cls, data):
        fridge_data = data["fridge"]
        instance = cls(fridge_data["owner"], fridge_data["nickname"])
        instance._Fridge__contents = fridge_data["contents"]
        instance._Fridge__authorized_users = [fridge_data["owner"]]
        return instance

2. 改造序列化测试代码

不要单独序列化单个实例,先把所有实例转为原生字典结构后,一次性序列化整个data对象:

import json

data = {
    'restaurants': []
}

# 测试代码,注意如果之前定义了res为Restaurant的别名可以保留,否则直接用Restaurant类名
test = Restaurant("Jac", "350b534")
test.add_fridge()
test.add_fridge()
# 先转成字典再加入列表
data['restaurants'].append(test.to_dict())

# 一次性序列化整个数据结构写入文件
with open("restaurant_data.json", "w", encoding="utf-8") as f:
    json.dump(data, f, indent=4, ensure_ascii=False)

3. 应用重启读取数据(可选)

with open("restaurant_data.json", "r", encoding="utf-8") as f:
    loaded_data = json.load(f)

# 转回可直接调用add_fridge、add_to_fridge等方法的Restaurant实例列表
restaurant_list = [Restaurant.from_dict(item) for item in loaded_data["restaurants"]]

额外说明

Python中双下划线开头的属性会触发名称修饰,类外部访问时需要写成_类名__属性名的格式,类内部可以直接用self.__属性名访问,上述封装的方法已经处理了私有属性的读写问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 07:06:03