轻松地在json之间序列化数据类

dc-json的Python项目详细描述


dc json

这个库提供了一个简单的api,用于编码和解码数据类到json和从json到json的数据类。

它是递归的(请参阅下面的注意事项),因此您可以轻松地使用嵌套的数据类。 除了 py to json table,此库支持以下功能:

  • 支持任意类型的集合。 映射类型编码为json对象,类型编码为json字符串。 任何其他集合类型都被编码为json数组,但被解码为原始集合类型。
  • 日期时间 物体。datetime使用 时间戳。 正如datetime文档中所指定的,如果您的datetime对象是幼稚的,它将 当调用.timestamp()时,假设您的系统是本地时区。杰森努尔斯 对应于数据类中的datetime字段进行解码 进入日期时间感知对象,并将tzinfo设置为系统本地时区。 因此,如果对DateTime原始对象进行编码,则将解码为 日期时间感知对象。这很重要,因为编码和解码不会 严格地说是相反的。如果要覆盖此默认值,请参阅本节 行为(例如,如果要使用ISO)。
  • 对象。他们 编码为str(json字符串)。

最新版本与Python3.7和Python3.6(带有数据类backport)兼容。

快速启动

pip安装dc json

方法1:类装饰器
fromdataclassesimportdataclassfromdc_jsonimportdataclass_json@dataclass_json@dataclassclassPerson:name:strlidatong=Person('lidatong')# Encoding to JSONlidatong.to_json()# '{"name": "lidatong"}'# Decoding from JSONPerson.from_json('{"name": "lidatong"}')# Person(name='lidatong')

请注意,@dataclass\u json装饰符必须堆叠在@dataclass之上。 装饰工(订单问题!)

方法2:从mixin继承
fromdataclassesimportdataclassfromdc_jsonimportDataClassJsonMixin@dataclassclassPerson(DataClassJsonMixin):name:strlidatong=Person('lidatong')# A different example from Approach 1 above, but usage is the exact sameassertPerson.from_json(lidatong.to_json())==lidatong

选择适合你口味的方法。在实现上的差异是 在使用中不可见。

如何…

将我的数据类与json数组或对象一起使用?

fromdataclassesimportdataclassfromdc_jsonimportdataclass_json@dataclass_json@dataclassclassPerson:name:str

编码成包含我的数据类实例的json数组

people_json=[Person('lidatong')]Person.schema().dumps(people_json,many=True)# '[{"name": "lidatong"}]'

解码包含我的数据类实例的json数组

people_json='[{"name": "lidatong"}]'Person.schema().loads(people_json,many=True)# [Person(name='lidatong')]

作为包含我的数据类(如http)的较大json对象的一部分进行编码 请求/响应)

importjsonperson_dict=Person.schema().dump(Person('lidatong'))response_dict={'response':{'person':person_dict}}response_json=json.dumps(response_dict)

在这种情况下,我们做两个步骤。首先,我们将数据类编码为 使用schema()dump>而不是json字符串。 向下滚动可找到相应的部分。

其次,我们利用内置的json.dumps将我们的dataclass序列化为 一个json字符串。

作为包含我的数据类(如http)的较大json对象的一部分解码 响应)

importjsonresponse_dict=json.loads('{"response": {"person": {"name": "lidatong"}}}')person_dict=response_dict['response']person=Person.schema().load(person_dict)

与上面的编码类似,我们利用内置的json模块。

首先,调用json.loads将整个json对象读入 字典。然后我们访问包含 我们要解码的人。(response dict['response'])。

其次,我们使用person.schema()加载字典。

编码或解码成pyth在列表/字典上而不是json上?

这可以通过调用.schema()然后使用相应的 编码器/解码器方法,即。。加载(…)/。转储(…)

编码到一个python字典中

person=Person('lidatong')Person.schema().dump(person)# {"name": "lidatong"}

编码到python字典列表中

people=[Person('lidatong')]Person.schema().dump(people,many=True)# [{"name": "lidatong"}]

将字典解码为单个数据类实例

fromdataclassesimportdataclassfromdc_jsonimportdataclass_json@dataclass_json@dataclassclassPerson:name:strlidatong=Person('lidatong')# Encoding to JSONlidatong.to_json()# '{"name": "lidatong"}'# Decoding from JSONPerson.from_json('{"name": "lidatong"}')# Person(name='lidatong')
0

将字典列表解码为数据类实例列表

fromdataclassesimportdataclassfromdc_jsonimportdataclass_json@dataclass_json@dataclassclassPerson:name:strlidatong=Person('lidatong')# Encoding to JSONlidatong.to_json()# '{"name": "lidatong"}'# Decoding from JSONPerson.from_json('{"name": "lidatong"}')# Person(name='lidatong')
1

处理解码时丢失的或可选的字段值?

默认情况下,数据类中使用default或 如果 正在解码的JSON中缺少相应字段。

解码缺少字段的json

fromdataclassesimportdataclassfromdc_jsonimportdataclass_json@dataclass_json@dataclassclassPerson:name:strlidatong=Person('lidatong')# Encoding to JSONlidatong.to_json()# '{"name": "lidatong"}'# Decoding from JSONPerson.from_json('{"name": "lidatong"}')# Person(name='lidatong')
2

注意,json中的用指定的默认"student"填充了字段name。 当它从json中丢失时。

有时您有输入为可选的字段,但您没有 必须要指定默认值。在这种情况下,您可以使用 inferu missingkwarg to makefrom_json将缺少的字段值推断为none

解码无默认值的可选字段

fromdataclassesimportdataclassfromdc_jsonimportdataclass_json@dataclass_json@dataclassclassPerson:name:strlidatong=Person('lidatong')# Encoding to JSONlidatong.to_json()# '{"name": "lidatong"}'# Decoding from JSONPerson.from_json('{"name": "lidatong"}')# Person(name='lidatong')
3

我个人建议您使用数据类默认值,而不是使用 inferu missing,但如果出于某种原因,您需要将 从字段的默认值进行json解码,这将允许您这样做。

说明

简单地说,在上面的例子中,在引擎盖下发生了什么:调用 .schema()将使此库生成 棉花糖模式 为你。它还填充相应的对象钩子,使棉花糖 将在加载时创建数据类的实例(例如 person.schema().load返回一个person)而不是返回一个dict 默认在棉花糖中。

性能说明

.schema()不缓存(它在每次调用时都会生成架构),因此如果 有一个嵌套的数据类,您可能希望将结果保存到变量中 避免每次使用都重新生成架构。

fromdataclassesimportdataclassfromdc_jsonimportdataclass_json@dataclass_json@dataclassclassPerson:name:strlidatong=Person('lidatong')# Encoding to JSONlidatong.to_json()# '{"name": "lidatong"}'# Decoding from JSONPerson.from_json('{"name": "lidatong"}')# Person(name='lidatong')
4

覆盖特定字段的默认"编码/解码/棉花糖"字段?

参见覆盖

棉花糖互操作

使用dataclass jsondecorator或混入dataclassjsonmixin将 为您提供一个附加的方法.schema()

.schema()生成的架构完全等同于手动创建 数据类的棉花糖架构。您可以参考棉花糖API文档 要了解其他方法,可以使用.schema()返回的模式

您可以向.schema()传递与在 构造一个PersonSchema实例,例如.schema(many=true),它们将 转到棉花糖模式。

fromdataclassesimportdataclassfromdc_jsonimportdataclass_json@dataclass_json@dataclassclassPerson:name:strlidatong=Person('lidatong')# Encoding to JSONlidatong.to_json()# '{"name": "lidatong"}'# Decoding from JSONPerson.from_json('{"name": "lidatong"}')# Person(name='lidatong')
5

覆盖/扩展

覆盖

例如,您可能希望使用iso格式对datetime对象进行编码/解码 而不是默认的时间戳

fromdataclassesimportdataclassfromdc_jsonimportdataclass_json@dataclass_json@dataclassclassPerson:name:strlidatong=Person('lidatong')# Encoding to JSONlidatong.to_json()# '{"name": "lidatong"}'# Decoding from JSONPerson.from_json('{"name": "lidatong"}')# Person(name='lidatong')
6

延伸

类似地,您可能需要扩展dc-json来编码对象。

fromdataclassesimportdataclassfromdc_jsonimportdataclass_json@dataclass_json@dataclassclassPerson:name:strlidatong=Person('lidatong')# Encoding to JSONlidatong.to_json()# '{"name": "lidatong"}'# Decoding from JSONPerson.from_json('{"name": "lidatong"}')# Person(name='lidatong')
7

如您所见,您可以通过 可呼叫:

  • 编码器:一个可调用的,当编码为json时将调用它来转换字段值
  • 解码器:一个可调用的,从json解码时将调用它来转换json值
  • mm_field:一个棉花糖字段,它将影响涉及.schema()
  • 的任何操作的行为

注意,无论您使用 。到json/转储/转储 从json加载。所以明智地应用覆盖/扩展,确保 仔细考虑encode/decode/mm_字段的交互是否与您期望的一致!

更大的示例

fromdataclassesimportdataclassfromdc_jsonimportdataclass_json@dataclass_json@dataclassclassPerson:name:strlidatong=Person('lidatong')# Encoding to JSONlidatong.to_json()# '{"name": "lidatong"}'# Decoding from JSONPerson.from_json('{"name": "lidatong"}')# Person(name='lidatong')
8

注意事项

包含正向引用的数据类(例如递归数据类)是 当前不支持。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java InputStream对象在声明后关闭   java未定义名为“transactionManager”的bean重命名transactionManager   java“jar”命令何时会拒绝将类添加到java中。jar文件?   java JPA标准依赖WHERE子句   安卓中从SD卡读取文本文件时出现java错误   java直接启用类似位置的权限   使用@WebMvcTest和Mockito-BDDMockito对SpringBoot-RestController进行java测试   java JSESSIONID存储在哪里?   java jtextarea鼠标事件覆盖容器鼠标事件   java DRL无法解析动态加载的类   java是从一个方法返回多个对象的最简单方法   java自定义按钮/编辑框是否不可见?   java GUI如何在保存用户输入的同时在面板或框架之间切换   swing Java自定义JSlider不会更新   GridBagLayout中的java超过1个JPanel   java从ProjectReactor中的flux中采样除第一个元素外的所有元素   Java泛型和泛型类型   Java代码生成宽指令的jvm