Python: обработка новых строк в json.load() vs json.loads()

71
8

Согласно этому ответу, строки новой строки в строке JSON всегда должны быть экранированы. Это не кажется необходимым, когда я загружаю JSON с помощью json.load().

Я сохранил следующую строку в файле:

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

Загрузка JSON с помощью json.load() не вызывает исключения, хотя \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() ли json.load() \n внутри файлового объекта? Следует ли всегда делать \\n независимо от того, будет ли JSON считываться json.load() или json.loads()?

спросил(а) 2017-08-08T17:15:00+03:00 3 года, 2 месяца назад
1
Решение
107

json.load() читает из дескриптора файла, а json.loads() читает из строки.

В вашем файле \n правильно кодируется как символ новой строки и не отображается в строке как два символа, а как правильный пустой символ, который вы знаете.

Но внутри строки, если вы не удваиваете escape \\n тогда загрузчик считает, что это управляющий символ. Но новая строка не является управляющей последовательностью для JSON (новая строка на самом деле является символом, как и любой другой).

При удвоении обратной косой черты вы фактически получаете реальную строку с \n в ней, и только тогда Python преобразует \n в символ новой строки.

ответил(а) 2017-08-08T17:26:00+03:00 3 года, 2 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема