Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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()?
like image 911
Dirty Penguin Avatar asked Aug 08 '17 14:08

Dirty Penguin


People also ask

What is the difference between JSON load and JSON loads in Python?

The json. load() is used to read the JSON document from file and The json. loads() is used to convert the JSON String document into the Python dictionary.

How does Python handle newlines in JSON?

Now in-order to print the statements in different lines we need to use '\\n' (backward slash). As we now know the technique to print in newlines, now just add '\\n' wherever you want. Now, as it is a JSON we need to parse it in order to print it. So use JSON.

Does JSON care about newlines?

JSON strings do not allow real newlines in its data; it can only have escaped newlines.

What is the difference between JSON loads and dumps?

loads() takes in a string and returns a json object. json. dumps() takes in a json object and returns a string.


2 Answers

json.load() reads from a file descriptor and json.loads() reads from a string.

Within your file, the \n is properly encoded as a newline character and does not appear in the string as two characters, but as the correct blank character you know.

But within a string, if you don't double escape the \\n then the loader thinks it is a control character. But newline is not a control sequence for JSON (newline is in fact a character like any other).

By doubling the backslash you actually get a real string with \n in it, and only then will Python transform the \n into a newline char.

like image 62
Fabien Avatar answered Oct 24 '22 03:10

Fabien


EDITED: Already answered here: https://stackoverflow.com/a/16544933/1054458

Maybe the strict option can help:

test.py:

import json

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

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

output:

$> python test.py
foo
bar
like image 43
FarK Avatar answered Oct 24 '22 04:10

FarK