【问题标题】:difference between str(dict) and json.dumps(dict)str(dict) 和 json.dumps(dict) 的区别
【发布时间】:2018-05-18 20:02:06
【问题描述】:

str(a dictionary)json.dumps(a dictionary) 的输出有什么区别?如果我打印它们,它们看起来是一样的。它们的属性(根据dir)似乎也相同(见下文)。但我知道肯定有区别。能给我解释一下吗?

import json

aDictionary= {"first": 42, "second":21}
s = str(aDictionary)
j = json.dumps(aDictionary)
s == j # returns false
dir(s) == dir(j) # returns true

【问题讨论】:

  • str(dict) 不会生成有效的 JSON。
  • 感谢您的评论。是的,我经历过,但我想更好地了解两个看起来非常相似的事物之间的区别。
  • 不要使用dict作为变量名。如果您打印结果,您会看到差异;来自str"{'first': 42, 'second': 21}" 和来自 json:'{"first": 42, "second": 21}'。注意键的字符串周围的双引号。
  • Of course dir() 返回相同的属性和方法列表。 sj 都是字符串。这并没有说明 这些字符串的内容
  • s == j # 返回 false,因为在由字符组成的字符串中,两者都是字符串,但逗号序列不同。来自str:“{'first':42,'second':21}”和来自json:'{“first”:42,“second”:21}'。看到逗号序列在两者中都不同,所以很明显比较会带来错误。因为两个字符串只有在对应的地方有匹配的字符时才需要相等。

标签: python json dictionary


【解决方案1】:

str(aDictionary)(以及repr(aDictionary))生成您的字典的Python 表示。这种表示有助于调试,仅此而已。对于字典和字符串等内置类型,您将获得一个有效的 Python 语法表示。 Python 语法和 JSON 语法可能看起来相似,但不是一回事

  • Python 对字符串文字使用单引号和双引号。 JSON 只允许使用双引号。
  • Python Unicode 字符串使用\<single letter>\xhh\uhhhh\Uhhhhhhhh 转义序列来编码Unicode 代码点;后一种形式用于非 BMP 代码点。 JSON 使用较小范围的 \<single letter> 转义以及 \uhhhh 形式,并为非 BMP 代码点编码 UTF-16 代理对(因此每个代码点有两个 \uhhhh 序列)。
  • Python 使用 None 对象,JSON 使用 null 作为特殊的“不存在”标记值。
  • Python 使用TrueFalse 作为布尔值,JSON 使用truefalse
  • Python 字典键可以是任何可散列类型,JSON 仅支持字符串。

所以str(dictionary) 在大多数情况下不会产生有效的 JSON 输出;只有当您的所有键和值都是 BMP 字符串并且值中至少有一个单引号时,您才能最终得到一个也可以被解析为有效 JSON 的文档。

就您的具体示例而言,请注意str(aDictionary) 生成的文档带有单引号json.loads() 无法加载此文档,因为它不是有效的 JSON:

>>> import json
>>> aDictionary = {"first": 42, "second":21}
>>> str(aDictionary)
"{'first': 42, 'second': 21}"
>>> json.loads(str(aDictionary))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/json/__init__.py", line 354, in loads
    return _default_decoder.decode(s)
  File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/json/decoder.py", line 355, in raw_decode
    obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

永远不要使用str(pythonobject) 作为序列化。尽管ast.literal_eval() function 可以从字符串表示中加载合理数量的 Python 内置类型,但它比使用 JSON 执行相同的工作要慢得多,或者如果 JSON 不适合您的需要,则使用更复杂的data persistence format

【讨论】:

  • 伟大而准确的答案。
猜你喜欢
  • 1970-01-01
  • 2012-04-21
  • 1970-01-01
  • 2013-01-15
  • 2021-04-24
  • 1970-01-01
  • 2014-01-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多