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

时间:2018-12-26 11:23:48

标签: python json python-attrs

我想使用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类,但是我尝试过的所有方法都以某种方式返回了属性。

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

(我是cattrs的作者,也是attrs的核心撰稿人。)

你好

根据定义,attrs Python类将在实例class _DetailScreenState extends State<DetailScreen> { @override initState() { SystemChrome.setEnabledSystemUIOverlays([]); super.initState(); } @override void dispose() { //SystemChrome.restoreSystemUIOverlays(); SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values); super.dispose(); } @override Widget build(BuildContext context) { return GestureDetector( child: Scaffold ( body: Center( child: Hero( tag: widget.tag, child: CachedNetworkImage( imageUrl: widget.url, placeholder: Center(child: Container(width: 32, height: 32,child: new CircularProgressIndicator())), errorWidget: new Icon(Icons.error), ), ), ), ), onTap: () { Navigator.pop(context); }, ); } } 中拥有其所有字段。当您说结构“应该返回仅具有A和B属性的对象”时,我假设您在尝试访问__dict__时希望返回的实例抛出AttributeError

据我所知,attrs无法做到这一点,也不是attrs的精神所在。您已将类定义为具有三个属性,因此它应该在这些属性中具有值。

您可以做的是将obj.C用作缺失值的值标记;这是通常在Python中表示缺失值的常用方法。该代码段变为:

None

您不希望期望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) 实例的代码必须处理神秘缺失的属性,对吧?