Python: Handling newlines in json.load() vs json.loads()

Viewed 18665

According to this answer, newlines in a JSON string should always be escaped. This does not appear to be necessary when I load the JSON with json.load().

I've saved the following string to file:

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

Loading the JSON with json.load() does not throw an exception, even though the \n is not escaped:

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

However, if I use json.loads(), I get an exception:

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

My questions:

  1. Does json.load() automatically escape \n inside the file object?
  2. Should one always do \\n regardless of whether the JSON will be read by json.load() or json.loads()?
3 Answers

The mistake in here is: When you use notepad to open a text file, and it says:

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

The "\" and "n" are separate characters, like any other characters in this file.

When in python program, you write:

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

do a test:

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

Don't miss the most interesting part: The \n in here is ONE character, in s[16], which means ASCII=10, a control character.

This control character means Carriage Return, or a new line. Anyway, with the existing of this control character, it is failed to be loaded as a JSON object.

You actually have to write

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

to make it exactly the same as in the text file.

Related