print loads example dict create python json escaping

loads - python json get value



Python: json.loads se ahoga en los escapes (3)

Tengo una aplicación que está enviando un objeto JSON (formateado con Prototype) a un servidor ASP. En el servidor, el módulo Python 2.6 "json" intenta cargar () el JSON, pero se está asfixiando con alguna combinación de barras invertidas. Observar:

>>> s ''{"FileExists": true, "Version": "4.3.2.1", "Path": "////host//dir//file.exe"}'' >>> tmp = json.loads(s) Traceback (most recent call last): File "<interactive input>", line 1, in <module> {... blah blah blah...} File "C:/Python26/lib/json/decoder.py", line 155, in JSONString return scanstring(match.string, match.end(), encoding, strict) ValueError: Invalid /escape: line 1 column 58 (char 58) >>> s[55:60] u''ost//d''

Así que la columna 58 es la barra invertida de escape. Pensé que esto se escapó correctamente! UNC es //host/dir/file.exe , por lo que acabo de duplicar en barras diagonales. Pero al parecer esto no es bueno. ¿Alguien puede ayudar? Como último recurso, estoy considerando convertir el / a / y luego de nuevo, pero esto me parece un verdadero truco.

¡Gracias por adelantado!


El json correcto es:

r''{"FileExists": true, "Version": "4.3.2.1", "Path": "////host//dir//file.exe"}''

Tenga en cuenta la letra r si la omite, también necesita escapar de Python.

>>> import json >>> d = json.loads(s) >>> d.keys() [u''FileExists'', u''Path'', u''Version''] >>> d.values() [True, u''////host//dir//file.exe'', u''4.3.2.1'']

Note la diferencia:

>>> repr(d[u''Path'']) "u''////////host////dir////file.exe''" >>> str(d[u''Path'']) ''////host//dir//file.exe'' >>> print d[u''Path''] //host/dir/file.exe

Python REPL imprime de forma predeterminada el repr(obj) para un objeto obj :

>>> class A: ... __str__ = lambda self: "str" ... __repr__ = lambda self: "repr" ... >>> A() repr >>> print A() str

Por lo tanto, la cadena de su s original no se escapó correctamente para JSON. Contiene ''/d'' y ''/f'' . print s debe mostrar ''//d'' contrario no es JSON correcto.

NOTA: la cadena JSON es una colección de cero o más caracteres Unicode, envueltos en comillas dobles, utilizando escapes de barra invertida ( json.org ). He omitido los problemas de codificación (es decir, la transformación de cadenas de bytes a Unicode y viceversa) en los ejemplos anteriores.


Ya que la excepción te da el índice del carácter de escape ofensivo, este pequeño truco que desarrollé podría ser bueno :)

def fix_JSON(json_message=None): result = None try: result = json.loads(json_message) except Exception as e: # Find the offending character index: idx_to_replace = int(e.message.split('' '')[-1].replace('')'','''')) # Remove the offending character: json_message = list(json_message) json_message[idx_to_replace] = '' '' new_message = ''''.join(json_message) return fix_JSON(json_message=new_message) return result


>>> s ''{"FileExists": true, "Version": "4.3.2.1", "Path": "////host//dir//file.exe"}'' >>> print s {"FileExists": true, "Version": "4.3.2.1", "Path": "//host/dir/file.exe"}

Realmente no has escapado a la cadena, por lo que se trata de analizar códigos de escape no válidos como /d o /f . Considere usar un codificador JSON bien probado, como json2.js .