【问题标题】:Python: Handling newlines in json.load() vs json.loads()Python:处理 json.load() 与 json.loads() 中的换行符
【发布时间】:2018-01-16 04:03:01
【问题描述】:

根据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)

我的问题:

  1. json.load() 是否会在文件对象中自动转义\n
  2. 无论 JSON 是否将被 json.load()json.loads() 读取,是否应该始终使用 \\n

【问题讨论】:

  • 您没有加载相同的字符串...您编写的字符串根本不是有效的 JSON。该文件可能有 \n 转义
  • @JBernardo 据我所知,文件是一样的:我保存了文件。
  • 那么就是你的问题了......你实际上在文本编辑器上的一个文件上写了\n,这与转义它是一样的。顺便说一句,您不应该手动编写 JSON。你有一个dumps 函数是有原因的
  • 那么当 Python 读取一个文件时,它会自动转义它找到的任何 \n 吗?还是文件编辑器在将文件保存到磁盘时做了一些特殊的事情?
  • 顺便说一句,这是一个人为的例子。我的实际用例是从一个 API 读取,该 API 提供一个 JSON 文件,其中包含未转义的 \n 字符。

标签: python json python-3.4


【解决方案1】:

已编辑:已在此处回答: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

【讨论】:

    【解决方案2】:

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

    {'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?"}'
    

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

    【讨论】:

      【解决方案3】:

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

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

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

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

      【讨论】:

      • 能否详细说明“控制字符”和“控制序列”的区别?
      • 没有太大区别,这里是同义词。我的意思是 JSON 的转义字符被限制用于编码二进制数据等目的,而不是换行符。而在 Python 中,控制序列可用于编码特殊字符,例如 \t\n...
      猜你喜欢
      • 2013-07-09
      • 2016-11-30
      • 2021-01-18
      • 2020-09-29
      • 2017-02-04
      • 2017-12-07
      • 2019-06-27
      • 1970-01-01
      相关资源
      最近更新 更多