python - json.dumps 和 json.loads 在任何字符串的列表上运行是否安全?
问题描述
在 Python 中对文本列表进行 JSON 序列化/反序列化时丢失信息是否有危险?
给定一个字符串列表lst
:
lst = ['str1', 'str2', 'str3', ...]
如果我跑
lst2 = json.loads(json.dumps(lst))
总是会lst
完全一样lst2
(即lst == lst2
总是会导致True
)?或者是否有一些特殊的、不寻常的字符会破坏这些方法中的任何一种?
我很好奇,因为我将处理来自各种 Unicode 范围的许多不同和不寻常的字符,我想绝对确定这个过程是 100% 健壮的。
解决方案
取决于您所说的“完全相同”。我们可以确定三个不同的问题:
语义身份。您读入的内容与您写回的内容在含义上是等价的,只要它首先是明确定义的。Python(取决于版本)可能会重新排序字典键,并且对于某些代码点通常更喜欢 Unicode 转义而不是文字字符,反之亦然。
>>> json.loads(json.dumps("\u0050\U0001fea5\U0001f4a9")) 'P\U0001fea5'
词汇身份。没有。如上所示,Unicode 代码点的 JSON 表示可以以不同的方式进行规范化,从而
\u0050
变成文字P
,可打印的表情符号可能会或可能不会类似地变成 Unicode 转义,反之亦然。(这与正确的Unicode 规范化不同,后者确保同形文字变成相同的精确代码点。)
垃圾进,同样的垃圾出。没有。如果您有无效的输入,Python 通常会崩溃而不是通过它,尽管您可以通过捕获错误和/或传递标志来修改其中的一些以请求不那么严格的行为。
>>> json.loads(r'"\u123"') File "<stdin>", line 1 SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 0-4: truncated \uXXXX escape >>> print(json.loads(r'"\udcff"')) ? >>> #!? should probably crash or moan instead!
您似乎在询问第一种情况,但如果您不确定如何处理无效的 Unicode 数据,第三种情况可能会严重影响您。
如果您关心磁盘上的 JSON 在版本之间是等效的,则第二种情况会有所不同;这对你来说似乎并不重要,但这个问题的未来访问者可能会很在意。
推荐阅读
- postgresql - 重命名后postgres数据库不存在
- rust - Rust 指针遵从向量
- frida - frida - defpackage 类未在 android 中列出
- javascript - 为固定背景图像设置滚动限制?
- java - 在 SpringBoot 中使用 @FeignClient 上传文件
- java - 多模块项目的 Maven 分发管理
- xml - 从powershell中的多个xml文件中选择多个节点?
- javascript - 用于 React 的 Plesk Obsidian NodeJS 给我错误
- firebase - 如何粘贴 JSON 数据或将 JSON 文件导入 Firestore 集合
- macos - 如何在 MAC 上将 Appium 连接到 Visual Studio 2019?