python-3.5 - 滤锅:如何处理嵌套模式的空值
问题描述
使用滤锅 1.5.1,如果我传递null
给由嵌套模式定义的属性:
class ChildSchema(colander.Schema):
a = colander.SchemaNode(colander.Integer(), missing=None)
b = colander.SchemaNode(colander.Integer(), missing=None)
class ParentSchema(colander.Schema):
c = colander.SchemaNode(colander.Integer(), missing=None)
d = ChildSchema(missing=None)
example json:
{
"c": 1,
"d": null
}
然后在反序列化时出现此错误:
"\"None\" is not a mapping type: Does not implement dict-like functionality."
未按d
预期传递属性函数,并反序列化为None
. 如何正确处理反序列化null
传递给嵌套模式的值?None
根据文档,
我希望行为能够返回。反序列化组合
解决方案
请考虑以下几点:
您需要以下导入。
import colander
from colander import SchemaType, Invalid, null
以下与您的子架构相同。
class ChildSchema(colander.Schema):
a = colander.Schema(colander.Integer(), missing=None)
b = colander.Schema(colander.Integer(), missing=None)
下面是所有魔法发生的地方。我们创建自己的类型。请注意,它可能缺少滤锅 SchemaTypes 中的内置函数可能提供的一些基本功能(如序列化)。如果接收到的对象为 null 或 None ,则返回它而不进行任何更改。如果它不是 null 或 None 并且不是字典,它将引发错误,如果它是字典,它将使用您的 ParentSchema 序列化,即使 Parent 的属性为 null 或 None ({"d": null} )。
class MyType(SchemaType):
def deserialize(self, node, cstruct):
if cstruct is null:
return null
if cstruct is None:
return None
if not isinstance(cstruct, dict):
raise Invalid(node, '%r is not an object' % cstruct)
else:
return ChildSchema().deserialize(cstruct)
我们使用魔法类型创建父模式:
class ParentSchema(colander.Schema):
c = colander.SchemaNode(colander.Integer(), missing=None)
d = colander.SchemaNode(MyType(), missing=None)
“d”将按照您的意愿反序列化。现在让我们看一些它的用法示例:
schema = ParentSchema()
示例 1.“d”为空(主要问题)
schema.deserialize({"c": 1, "d": null})
输出 1
{"c": 1, "d": None}
示例 2.“d”为无
schema.deserialize({"c": 1, "d": None})
输出 2
{"c": 1, "d": None}
示例 3. 正常行为
schema.deserialize({'c': 1, 'd': {'a': 1}})
输出 3。
{'c': 1, 'd': {'a': 1, 'b': None}}
示例 5. 错误 "d" 不是 dict
schema.deserialize({'c': 1, 'd': [] })
输出 5
# Invalid: {'d': '[] is not an object'}
示例 6. 错误验证器不是数字
schema.deserialize({'c': 1, 'd': {'a': "foobar"}})
输出 6
# Invalid: {'a': u'"foobar" is not a number'}
为了写这个答案,我使用了https://docs.pylonsproject.org/projects/colander/en/latest/extending.html作为来源。
推荐阅读
- python - 如何创建包含 sqlite 数据库的 python exe 文件?
- android - Android WebView 和 webrtc hello world 示例
- angular - 如何在 TypeScript 中正确键入 RXJS WebSocket?
- javascript - 如何通过单击按钮的数据触发 setState 函数以从子组件到父组件做出反应
- python - 熊猫数据框中一行的部分总和
- java - JAVA_HOME 设置未显示在工作区设置中以完成 W3C 验证扩展安装
- vba - 使用 VBA 从另一个工作表中隐藏受保护的列
- javascript - 如果我输入正确的答案,为什么我总是“错”?
- javascript - 解决 CountNonDivisible 代码问题
- typescript - 如何为条件类型赋值?