Python:处理json.load()vs json.loads()中的换行符

时间:2017-08-08 14:15:28

标签: python json python-3.4

根据{{3}},应始终转义JSON字符串中的换行符。当我使用json.load()加载JSON时,这似乎不是必需的。

我已将以下字符串保存到文件中:

{'text': 'Hello,\n How are you?'}

使用json.load()加载JSON不会引发异常,即使\n未转义:

>>> with open('test.json', 'r') as f:
...   json.load(f)
...
{'text': 'Hello,\n How are you?'}

但是,如果我使用json.loads(),我会得到一个例外:

>>> s
'{"text": "Hello,\n How are you?"}'
>>> json.loads(s)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:\Python34\lib\json\__init__.py", line 318, in loads
    return _default_decoder.decode(s)
  File "c:\Python34\lib\json\decoder.py", line 343, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "c:\Python34\lib\json\decoder.py", line 359, in raw_decode
    obj, end = self.scan_once(s, idx)
ValueError: Invalid control character at: line 1 column 17 (char 16)

我的问题:

  1. json.load()会自动转义文件对象中的\n吗?
  2. 无论\\n还是json.load()是否会读取JSON,是否应始终json.loads()

3 个答案:

答案 0 :(得分:9)

json.load()从文件描述符读取,json.loads()从字符串中读取。

在您的文件中,\n被正确编码为换行符,并且不会在字符串中显示为两个字符,而是作为您知道的正确空白字符。

但是在一个字符串中,如果你没有双重转义\\n,那么加载程序认为它是一个控制字符。但换行不是JSON的控制序列(换行实际上是一个像任何其他人一样的字符)。

通过加倍反斜杠,你实际上会得到一个包含\n的真实字符串,然后Python才会将\n转换为换行符。

答案 1 :(得分:0)

这里的错误是: 当您使用记事本打开文本文件时,它说:

{'text': 'Hello,\n How are you?'}

“ \”和“ n”是单独的字符,就像该文件中的其他任何字符一样。

在python程序中,您编写:

s='{"text": "Hello,\n How are you?"}'

进行测试:

>>> s[15]
','
>>> s[16]
'\n'
>>> s[17]
' '

不要错过最有趣的部分:\ n是s [16]中的一个字符,表示ASCII = 10,是控制字符。

此控制字符表示回车或换行。无论如何,由于存在此控制字符,因此无法将其作为JSON对象加载。

您实际上必须写

s='{"text": "Hello,\\n How are you?"}'

使其与文本文件完全相同。

答案 2 :(得分:0)

已编辑:已在此处回答:https://stackoverflow.com/a/16544933/1054458

也许 strict 选项可以提供帮助:

test.py:

import json

s = '''{
"asdf":"foo
bar"
}'''

print(json.loads(s, strict=False)["asdf"])

输出:

$> python test.py
foo
bar