序列化为 JSON 数据数组 类
serializing to JSON an array of data classes
我有一个 数据数组 classes 我需要 序列化 到 JSON。我将列表包装在 class (Persons
)
中
@attrs.frozen
class Person:
name: str
age: int
grades: Dict[str, int]
@attrs.define
class Persons:
persons: List[Person] = attrs.field(factory=list)
def add(self, person: Person) -> None:
self.persons.append(person)
def run(filename: str) -> None:
college = Persons()
college.add(Person("uzi" , 51, {"math": 100, "cs": 90}))
college.add(Person("dave", 76, {"math": 94, "music": 92}))
college.add(Person("dan", 22, {"bible": 98}))
with open(filename, "w+") as fl:
fl.write(f"{json.dumps(attrs.asdict(college), indent=4)}\n")
我能否以某种方式去掉包装 class 并仍然轻松地序列化 List[Person]
?
您可以使用 json.dumps
函数的 default
参数并传递函数 attrs.asdict
来序列化它。
我添加了“persons”键,使其与您的代码输出匹配。
import json
import attrs
@attrs.frozen
class Person:
name: str
age: int
grades: dict[str, int]
def run(filename: str) -> None:
college = []
college.append(Person("uzi", 51, {"math": 100, "cs": 90}))
college.append(Person("dave", 76, {"math": 94, "music": 92}))
college.append(Person("dan", 22, {"bible": 98}))
with open(filename, "w+") as fl:
fl.write(
f"{json.dumps({'persons': college}, default=attrs.asdict, indent=4)}\n"
)
run("my_json.json")
输出
{
"persons": [
{
"name": "uzi",
"age": 51,
"grades": {
"math": 100,
"cs": 90
}
},
{
"name": "dave",
"age": 76,
"grades": {
"math": 94,
"music": 92
}
},
{
"name": "dan",
"age": 22,
"grades": {
"bible": 98
}
}
]
}
对于 dataclasses
的高级方法,我建议查看 dataclass-wizard
库。
它提供了一些通用且有用的实现,例如 Container 类型,它只是 Python.
中 list
类型的便利包装器
它还公开了有用的 mixin 类,这使得使用 YAML/JSON 文件更容易,如下所示。
from dataclasses import dataclass
from dataclass_wizard import Container, JSONListWizard, JSONFileWizard
# optional: extend from `JSONListWizard`, so de-serializing a list results
# in a `Container` object; though you could also use `JSONWizard` instead.
# also extend from `JSONFileWizard`, so we can de-serialize data back from
# a JSON file.
@dataclass(frozen=True)
class Person(JSONListWizard, JSONFileWizard):
name: str
age: int
grades: dict[str, int]
def run(filename: str) -> None:
# create a `Container` object, which is just a wrapper around a Python `list`
college = Container[Person]()
college.append(Person("uzi", 51, {"math": 100, "cs": 90}))
college.append(Person("dave", 76, {"math": 94, "music": 92}))
college.append(Person("dan", 22, {"bible": 98}))
# serialize the list of instances to a json file
college.to_json_file(filename, indent=4)
run('my_file.json')
# now, read it back :-)
people = Person.from_json_file('my_file.json')
my_file.json
的内容如下所示:
[
{
"name": "uzi",
"age": 51,
"grades": {
"math": 100,
"cs": 90
}
},
{
"name": "dave",
"age": 76,
"grades": {
"math": 94,
"music": 92
}
},
{
"name": "dan",
"age": 22,
"grades": {
"bible": 98
}
}
]
我有一个 数据数组 classes 我需要 序列化 到 JSON。我将列表包装在 class (Persons
)
@attrs.frozen
class Person:
name: str
age: int
grades: Dict[str, int]
@attrs.define
class Persons:
persons: List[Person] = attrs.field(factory=list)
def add(self, person: Person) -> None:
self.persons.append(person)
def run(filename: str) -> None:
college = Persons()
college.add(Person("uzi" , 51, {"math": 100, "cs": 90}))
college.add(Person("dave", 76, {"math": 94, "music": 92}))
college.add(Person("dan", 22, {"bible": 98}))
with open(filename, "w+") as fl:
fl.write(f"{json.dumps(attrs.asdict(college), indent=4)}\n")
我能否以某种方式去掉包装 class 并仍然轻松地序列化 List[Person]
?
您可以使用 json.dumps
函数的 default
参数并传递函数 attrs.asdict
来序列化它。
我添加了“persons”键,使其与您的代码输出匹配。
import json
import attrs
@attrs.frozen
class Person:
name: str
age: int
grades: dict[str, int]
def run(filename: str) -> None:
college = []
college.append(Person("uzi", 51, {"math": 100, "cs": 90}))
college.append(Person("dave", 76, {"math": 94, "music": 92}))
college.append(Person("dan", 22, {"bible": 98}))
with open(filename, "w+") as fl:
fl.write(
f"{json.dumps({'persons': college}, default=attrs.asdict, indent=4)}\n"
)
run("my_json.json")
输出
{
"persons": [
{
"name": "uzi",
"age": 51,
"grades": {
"math": 100,
"cs": 90
}
},
{
"name": "dave",
"age": 76,
"grades": {
"math": 94,
"music": 92
}
},
{
"name": "dan",
"age": 22,
"grades": {
"bible": 98
}
}
]
}
对于 dataclasses
的高级方法,我建议查看 dataclass-wizard
库。
它提供了一些通用且有用的实现,例如 Container 类型,它只是 Python.
中list
类型的便利包装器
它还公开了有用的 mixin 类,这使得使用 YAML/JSON 文件更容易,如下所示。
from dataclasses import dataclass
from dataclass_wizard import Container, JSONListWizard, JSONFileWizard
# optional: extend from `JSONListWizard`, so de-serializing a list results
# in a `Container` object; though you could also use `JSONWizard` instead.
# also extend from `JSONFileWizard`, so we can de-serialize data back from
# a JSON file.
@dataclass(frozen=True)
class Person(JSONListWizard, JSONFileWizard):
name: str
age: int
grades: dict[str, int]
def run(filename: str) -> None:
# create a `Container` object, which is just a wrapper around a Python `list`
college = Container[Person]()
college.append(Person("uzi", 51, {"math": 100, "cs": 90}))
college.append(Person("dave", 76, {"math": 94, "music": 92}))
college.append(Person("dan", 22, {"bible": 98}))
# serialize the list of instances to a json file
college.to_json_file(filename, indent=4)
run('my_file.json')
# now, read it back :-)
people = Person.from_json_file('my_file.json')
my_file.json
的内容如下所示:
[
{
"name": "uzi",
"age": 51,
"grades": {
"math": 100,
"cs": 90
}
},
{
"name": "dave",
"age": 76,
"grades": {
"math": 94,
"music": 92
}
},
{
"name": "dan",
"age": 22,
"grades": {
"bible": 98
}
}
]