首页 > 解决方案 > 反序列化时处理 JSON 和 Python 之间差异的最佳方法是什么?

问题描述

我正在使用基于 python 的 API 处理消息传递服务。API 完成了大部分反序列化工作,将消息呈现到 python 字典中。但是,在某些情况下,呈现的字典包括元数据键/值对,其中值是尚未反序列化的字典的字符串呈现。我创建了一个简单的反序列化方法,但我不得不反复修改它以涵盖 python 和 JSON 之间的三个差异,即单引号与双引号、布尔值的大小写差异以及 None 与 null:

def deserializeMetaData(metaDataStr):
    metaDataStr = metaDataStr.replace("'",'"').replace('True', 'true').replace('False', 'false').replace('None', 'null')
    metaDataDict = json.loads(metaDataStr)
    return metaDataDict

metaDataStr = "{'SomeCount': 1, 'SomeOtherCount': 2, 'SomeBool': True, 'SomethingElse': None}" 
deserializeMetaData(metaDataStr)
{'SomeCount': 1, 'SomeOtherCount': 2, 'SomeBool': True, 'SomethingElse': None}

像我反复调用replace. 是否有另一种方法可以更好地涵盖这些和所有极端情况?

标签: pythonjsondeserialization

解决方案


可能被metaDataStr错误地解释为需要反序列化的 JSON。相反,将其视为字典的字符串文字会导致抽象语法树 (ast) 模块

安全地评估包含 Python 文字或容器显示的表达式节点或字符串。提供的字符串或节点只能由以下 Python 文字结构组成:字符串、字节、数字、元组、列表、字典、集合、布尔值和无。

这可用于安全地评估包含来自不受信任来源的 Python 值的字符串,而无需自己解析这些值。它不能评估任意复杂的表达式,例如涉及运算符或索引。

因此,以下足以将字符串转换为字典而不会出现问题:

import ast
    
metaDataStr = "{'SomeCount': 1, 'SomeOtherCount': 2, 'SomeBool': True, 'SomethingElse': None}"
d = ast.literal_eval(metaDataStr)
type(d)
Out[18]: dict

推荐阅读