如何使用 attrs 和 cattrs 使用可选字段反序列化 json

How to deserialize json with optional fields using attrs and cattrs

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

我之前使用漏勺来做这类事情,它在 colander.SchemaNode 构造函数中提供了一个 'missing' 参数,它通过将 '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)

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

感谢您的帮助。

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

您好,

根据定义,

属性 Python class 将在实例 __dict__ 中拥有其所有字段。当您说结构 "should return an object with only A and B attributes" 时,我假设您希望在尝试访问 obj.C.

时返回的实例抛出 AttributeError

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

你可以做的是使用None作为缺失值的值标记;这是通常表示 Python 中缺失值的常用方法。代码片段变为:

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 实例的代码必须处理神秘丢失的属性,对吗?