【问题标题】:Serializing a list of object instances nested within an object instance python序列化嵌套在对象实例python中的对象实例列表
【发布时间】:2021-11-24 03:41:22
【问题描述】:

我正在制作一个应用程序,让您可以登录或创建餐厅。作为餐厅老板,您可以添加/删除/编辑冰箱。我的最终目标是我有一个餐厅列表,我会写入一个 JSON 文件,并且每当我重新运行应用程序时,我都可以将这些数据拉入并模拟“成为餐厅老板”并编辑冰箱选择的餐厅。

我基本上想要这个:

data = {
    restaurants: [
        {
            restaurant: {
            name: "Peppy",
            pw: "123",
            fridges: [
                {
                    fridge: {
                        owner: restaurant.name,
                        contents: []
                    }
                }
            ]
        }
        }
    ]
}

我有以下两个类(显示相关方法):


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: ")
        self.__owned_fridges.append(fr(self.owner, nickname))
        print("Fridge added!")
 

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)

我的问题是为 JSON 序列化这个。我发现以下方法可以将餐厅对象序列化为 JSON,但不能将嵌套的冰箱对象序列化:

data = {
    'restaurants': []
}

# Testing code
test = res("Jac", "350b534")
test.add_fridge()
test.add_fridge()
data['restaurants'].append(json.dumps(test.__dict__))

我对python比较陌生,而且我来自js背景,所以我对语法还是很熟悉的。我的问题是,如何序列化冰箱的内部列表?

【问题讨论】:

  • 嗯,看起来像 nickname authorized_users 这样的一些字段将从序列化中排除,因为我在结果字典中看不到它们。

标签: python json oop


【解决方案1】:

首先,我建议查看dataclasses,因为它们将简化在 Python 中处理类的任务。使用数据类,您不需要定义像 __init____repr__ 这样的 dunder 方法,因为它们会默认自动生成。

对于您的特定用例,您可以使用可以传递给json.dumps 的可选default 可调用对象将嵌套类模型序列化为dict / JSON 字符串来解决问题。例如,您可以传递一个 lambda(它本质上是一个速记函数),例如 lambda o: o.__dict__,它会检索本质上不能序列化为 JSON 的对象的 __dict__ 属性,如下所示。

from __future__ import annotations

import json
from dataclasses import dataclass


@dataclass
class A:
    my_string: str
    b: list[B]


@dataclass
class B:
    my_int: int
    password: str


a = A('test', [B(2, '123'), B(5, '321')])
print(a)
# A(my_string='test', b=[B(my_int=2, password='123'), B(my_int=5, password='321')])

print(json.dumps(a, default=lambda o: o.__dict__))
# {"my_string": "test", "b": [{"my_int": 2, "password": "123"}, {"my_int": 5, "password": "321"}]}

但请注意,如果您需要先将数据类实例转换为 dict 实例,数据类还提供了一个辅助函数 asdict


不过,如果您有更高级的用例 - 例如,将 JSON 数据反序列化为嵌套类模型,或将 password 等数据类字段映射到 pw 等另一个 JSON 键,如列出的示例 - 我建议检查像 dataclass-wizard 这样的序列化库,它适用于上述嵌套数据类模型。

【讨论】:

    猜你喜欢
    • 2017-07-06
    • 1970-01-01
    • 2013-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-31
    • 2012-07-12
    • 1970-01-01
    相关资源
    最近更新 更多