序列化嵌套在对象实例中的对象实例列表 python
Serializing a list of object instances nested within an object instance python
我正在制作一款应用程序,您可以使用它登录或创建餐厅。作为餐厅老板,您可以 add/remove/edit 冰箱。我的最终目标是我有一个餐厅列表,我将其写入 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出身,所以对语法还是比较熟悉的。我的问题是,如何序列化冰箱的内部列表?
首先,我建议查看 dataclasses,因为它们会简化在 Python 中使用 classes 的任务。使用 dataclasses,您不需要定义像 __init__
和 __repr__
这样的 dunder 方法,因为它们会默认自动生成。
对于您的特定用例,您可以通过使用可选的 default
可调用项将嵌套 class 模型序列化为 dict
/ JSON 字符串来解决问题你可以传递给 json.dumps
。例如,您可以传递一个 lambda(它本质上是一个 shorthand 函数),例如 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"}]}
但请注意,如果您需要先将 dataclass 实例转换为 dict
实例,dataclasses 还提供了一个辅助函数 asdict
。
不过,如果您有更高级的用例 - 例如,将 JSON 数据反序列化为嵌套 class 模型,或映射数据 class 字段,例如password
到另一个 JSON 键,例如所列示例中的 pw
- 我建议检查一个序列化库,例如 dataclass-wizard,它适用于嵌套数据class模型同上。
我正在制作一款应用程序,您可以使用它登录或创建餐厅。作为餐厅老板,您可以 add/remove/edit 冰箱。我的最终目标是我有一个餐厅列表,我将其写入 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出身,所以对语法还是比较熟悉的。我的问题是,如何序列化冰箱的内部列表?
首先,我建议查看 dataclasses,因为它们会简化在 Python 中使用 classes 的任务。使用 dataclasses,您不需要定义像 __init__
和 __repr__
这样的 dunder 方法,因为它们会默认自动生成。
对于您的特定用例,您可以通过使用可选的 default
可调用项将嵌套 class 模型序列化为 dict
/ JSON 字符串来解决问题你可以传递给 json.dumps
。例如,您可以传递一个 lambda(它本质上是一个 shorthand 函数),例如 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"}]}
但请注意,如果您需要先将 dataclass 实例转换为 dict
实例,dataclasses 还提供了一个辅助函数 asdict
。
不过,如果您有更高级的用例 - 例如,将 JSON 数据反序列化为嵌套 class 模型,或映射数据 class 字段,例如password
到另一个 JSON 键,例如所列示例中的 pw
- 我建议检查一个序列化库,例如 dataclass-wizard,它适用于嵌套数据class模型同上。