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
答案 0 :(得分:10)
repr(aDictionary)
(以及\<single letter>
)会生成字典的 Python表示。此表示有助于调试而不再是。对于字典和字符串等内置类型,您将获得一个有效的 Python 语法表示。 Python语法和JSON语法可能看起来相似,但不一样。
\xhh
,\uhhhh
,\Uhhhhhhhh
和\<single letter>
转义序列来编码Unicode代码点;后一种形式用于非BMP代码点。 JSON使用较小范围的\uhhhh
转义符以及\uhhhh
表单,并为非BMP代码点编码UTF-16代理项对(因此每个代码点有两个None
个序列)。null
个对象,JSON使用True
作为特殊的“不存在”的标记值。False
和true
作为布尔值,JSON使用false
和str(dictionary)
。所以str(aDictionary)
不会产生有效的JSON输出,大部分时间都是如此;只有当你的所有键和值都是BMP字符串且值中至少有一个单引号时,你才能得到一个也可以被解析为有效JSON的文档。
就您的具体示例而言,请注意json.loads()
生成包含单引号的文档; >>> 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)
无法加载此文档,因为它不是有效的JSON:
str(pythonobject)
绝不要将Viewbox
用作序列化。虽然ast.literal_eval()
function可以从字符串表示中加载合理数量的Python内置类型,但它比使用JSON对同一作业慢很多,或者如果JSON没有,则更复杂data persistence format满足你的需求。