Python。在json.load()与json.load()中处理换行符

18 人关注

根据 这个答案 , 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(),我就会得到一个异常。

'{"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)

My questions:

  • Does json.load() automatically escape \n inside the file object?
  • Should one always do \\n regardless of whether the JSON will be read by json.load() or json.loads()?
  • 5 个评论
    你加载的不是同一个字符串...你写的那个根本不是有效的JSON。该文件可能有 \n 的转义。
    @JBernardo 据我所知,该文件是一样的:我保存了该文件。
    那么你的问题就来了...你实际上是在文本编辑器上的一个文件上写了 \n ,这和转义是一样的。顺便说一下,你不应该用手写JSON。你得到一个 dumps 函数是有原因的
    那么当 Python 读取一个文件时,它是否会自动转义它发现的任何 \n ?还是文件编辑器在将文件保存到磁盘时做了一些特别的事情?
    Btw,这是个有点矫揉造作的例子。我的实际用例是从一个API中读取,该API提供了一个包含未转义的 \n 字符的JSON文件。
    python
    json
    python-3.4
    Dirty Penguin
    Dirty Penguin
    发布于 2017-08-08
    3 个回答
    Fabien
    Fabien
    发布于 2020-09-03
    已采纳
    0 人赞同

    替换代码0】从文件描述符读取, json.loads() 从字符串读取。

    在你的文件中, \n 被正确地编码为换行字符,并且在字符串中不作为两个字符出现,而是作为你所知道的正确的空白字符。

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

    通过加倍反斜杠,你实际上得到了一个包含 \n 的真正的字符串,只有这样Python才会把 \n 转化为换行符。

    你能否详细说明 "控制字符 "和 "控制序列 "之间的区别?
    没有太大的区别,这里是同义词。我的意思是,JSON的转义字符只限于编码二进制数据等用途,而不是换行。而在Python中,控制序列可以用来编码特殊字符,如 \t \n ...
    FarK
    FarK
    发布于 2020-09-03
    0 人赞同

    已编辑。这里已经有了答案。 https://stackoverflow.com/a/16544933/1054458

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

    test.py:

    import json
    s = '''{
    "asdf":"foo
    print(json.loads(s, strict=False)["asdf"])
    

    output:

    $> python test.py
        
    Ben Lin
    Ben Lin
    发布于 2020-09-03
    0 人赞同

    这里的错误是。 当你用记事本打开一个文本文件时,它说。

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

    "/"和 "n "是独立的字符,与本文件中的其他字符一样。

    当在Python程序中,你写。

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

    做一个测试。

    >>> s[15]
    >>> s[16]
    >>> s[17]
    

    不要错过最有趣的部分:这里的n是一个字符,在s[16],这意味着ASCII=10,一个控制字符。