Python:在 json.load() 与 json.loads() 中处理换行符
Python: Handling newlines in json.load() vs json.loads()
根据 this answer,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)
我的问题:
json.load()
是否在文件对象中自动转义\n
?
- 无论 JSON 是否会被
json.load()
或 json.loads()
读取,是否应该始终执行 \n
?
json.load()
从文件描述符读取,json.loads()
从字符串读取。
在您的文件中,\n
被正确编码为换行符,在字符串中不是作为两个字符出现,而是作为您知道的正确空白字符出现。
但是在一个字符串中,如果你不对 \n
进行双重转义,那么加载器就会认为它是一个控制字符。但是换行符不是 JSON 的控制序列(换行符实际上和其他任何字符一样)。
通过将反斜杠加倍,您实际上得到了一个包含 \n
的真实字符串,然后 Python 才会将 \n
转换为换行符。
这里的错误是:
当你用记事本打开一个文本文件时,它显示:
{'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,一个控制字符。
这个控制字符表示回车符Return,或者换行。反正有这个控制符存在,作为JSON对象加载是失败的。
你实际上必须写
s='{"text": "Hello,\n How are you?"}'
使其与文本文件中的完全相同。
已编辑:已在此处回答:
也许 strict
选项可以提供帮助:
test.py:
import json
s = '''{
"asdf":"foo
bar"
}'''
print(json.loads(s, strict=False)["asdf"])
输出:
$> python test.py
foo
bar
根据 this answer,JSON 字符串中的换行符应始终进行转义。当我用 json.load()
.
我已将以下字符串保存到文件中:
{'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)
我的问题:
json.load()
是否在文件对象中自动转义\n
?- 无论 JSON 是否会被
json.load()
或json.loads()
读取,是否应该始终执行\n
?
json.load()
从文件描述符读取,json.loads()
从字符串读取。
在您的文件中,\n
被正确编码为换行符,在字符串中不是作为两个字符出现,而是作为您知道的正确空白字符出现。
但是在一个字符串中,如果你不对 \n
进行双重转义,那么加载器就会认为它是一个控制字符。但是换行符不是 JSON 的控制序列(换行符实际上和其他任何字符一样)。
通过将反斜杠加倍,您实际上得到了一个包含 \n
的真实字符串,然后 Python 才会将 \n
转换为换行符。
这里的错误是: 当你用记事本打开一个文本文件时,它显示:
{'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,一个控制字符。
这个控制字符表示回车符Return,或者换行。反正有这个控制符存在,作为JSON对象加载是失败的。
你实际上必须写
s='{"text": "Hello,\n How are you?"}'
使其与文本文件中的完全相同。
已编辑:已在此处回答:
也许 strict
选项可以提供帮助:
test.py:
import json
s = '''{
"asdf":"foo
bar"
}'''
print(json.loads(s, strict=False)["asdf"])
输出:
$> python test.py
foo
bar