【问题标题】:How to deserialize json with optional fields using attrs and cattrs如何使用 attrs 和 cattrs 反序列化带有可选字段的 json
【发布时间】:2019-05-24 16:16:29
【问题描述】:

我想使用 attr 和 cattrs 反序列化 MongoDB 文档。由于 noSQL 没有固定的模式,我需要以某种方式指向 attr.ib-s 可能会丢失它们,并且在这种情况下不要将它们添加到 dict 的对象中。

我之前使用过滤器来做这种事情,它在 colander.SchemaNode 构造函数中提供了一个“缺失”参数,它通过传递“colander.drop”作为参数来实现这一点。我想知道如何对这些库做同样的事情,我在文档中没有找到任何东西。所以:

import attr
from cattr import structure

@attr.s
class ABC:
    A: float = attr.ib()
    B: float = attr.ib()
    C: float = attr.ib()

d = {'A': 1, 'B': 2}
obj = structure(d, ABC)

应该返回一个只有 A 和 B 属性的对象。我一直在尝试使用一些参数(init、default...),甚至使用来自输入 lib 的 Optional 类,但是我尝试的所有方法都以某种方式返回了该属性。

感谢您的帮助。

【问题讨论】:

标签: python json python-attrs


【解决方案1】:

(我是 cattrs 的作者,也是 attrs 的核心贡献者。)

你好,

根据定义,一个 attrs Python 类的所有字段都在实例__dict__ 中。当您说结构“应该返回只有 A 和 B 属性的对象”时,我假设您希望在尝试访问 obj.C 时返回的实例抛出 AttributeError

据我所知,这对于 attrs 是不可能的,也不符合 attrs 的精神。您已将您的类定义为具有三个属性,因此它应该在这些属性中具有值。

您可以做的是使用None 作为缺失值的值标记;这是通常在 Python 中表示缺失值的常用方法。代码 sn -p 变为:

from typing import Optional

import attr
from cattr import structure

@attr.s
class ABC:
    A: float = attr.ib()
    B: float = attr.ib()
    C: Optional[float] = attr.ib(default=None)

d = {'A': 1, 'B': 2}
obj = structure(d, ABC)

您不希望期望ABC 实例的代码必须处理神秘缺失的属性,对吧?

【讨论】:

  • 嗨!其实,是的,我想要。但我的需求非常具体。在我的例子中,我使用该类来反序列化 MongoDB 文档,对数据进行一些转换,并将新信息上传到数据库。由于 MongoDB 没有固定的模式,我需要在具体文档中期望一些可选参数,如果它们被遗漏,我不想用 None 值上传它们。我的观点是在上传文档之前不必检查 None 字段。无论如何,如果不可能,我接受答案。非常感谢!
猜你喜欢
  • 2014-01-11
  • 2021-12-24
  • 2021-12-15
  • 1970-01-01
  • 1970-01-01
  • 2017-04-04
  • 1970-01-01
  • 1970-01-01
  • 2020-07-17
相关资源
最近更新 更多