Поскольку вы встраиваете JSON в строковый литерал Python, он сначала применяет правила экранирования Python, когда анализируется код Python и, следовательно, строковый литерал.
Значение сначала \"
интерпретируется на уровне Python, давая одиночный "
, затем этот единственный "
анализируется как JSON и терпит неудачу.
Вам необходимо:
- экранировать
\
так, чтобы он правильно интерпретировался как фактический символ \
в результирующей строке (просто удвойте его) - или используйте rawstrings (просто префикс строка с тройными кавычками
\
), это отключает большинство экранирований, обычно он используется для строковых литералов регулярных выражений, поскольку они часто используют \
, но они также подходят для JSON строковых литералов и других вложений
Ваша версия:
>>> loads("""{
... "*": {
... "picker": {
... "old": 49900,
... "description": "Meaning \"sunshine\" and \r\n- cm."
... }
... }
... }""")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "lib/python3.8/json/__init__.py", line 357, in loads
return _default_decoder.decode(s)
File "lib/python3.8/json/decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "lib/python3.8/json/decoder.py", line 353, in raw_decode
obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Expecting ',' delimiter: line 5 column 32 (char 78)
экранирование escape-символов:
>>> loads("""{
... "*": {
... "picker": {
... "description": "Meaning \\"sunshine\\" and \\r\\n- cm."
... }
... }
... }""")
{'*': {'picker': {'description': 'Meaning "sunshine" and \r\n- cm.'}}}
rawstring:
>>> loads(r"""{
... "*": {
... "picker": {
... "description": "Meaning \"sunshine\" and \r\n- cm."
... }
... }
... }""")
{'*': {'picker': {'description': 'Meaning "sunshine" and \r\n- cm.'}}}