2011-01-18 12 views
9

Tengo un archivo de configuración en JSON que contiene algunas variables como cadenas (siempre ascii). Estas cadenas se decodifican para unicode por defecto, pero como tengo que pasar estas variables a mis extensiones de Python C, las necesito como cadenas normales de Python. Por el momento estoy usando str(unicode) para convertir las cadenas JSON, pero una solución más elegante y menos detallada sería muy apreciada.Cómo decodificar JSON a str y no a unicode en Python (2.6)?

¿Hay alguna manera de cambiar la traducción predeterminada de cadena a unicode con un gancho personalizado JSONDecoder?

+0

Sí, una costumbre JSONDecoder debe ser capaz de saltarse la decodificación del str a Unicode y devuelve la cadena binaria en bruto. –

+0

@Lennart Regebro Intenté hacer eso y fallé: tuve que copiar y pegar para extender una gran cantidad de clases y constantes privadas de módulo. ¿Hay una manera simple de modificar JSONDecoder que no puedo ver? – TryPyPy

+0

@TryPyPy: No existen las constantes privadas de módulo en Python ... –

Respuesta

0

Vea si las respuestas a this question lo ayudan (en esa pregunta, el asker estaba usando simplejson).

1

No si no está dispuesto a perder algo de velocidad. Si es un poco más lento está bien, debe tener en cuenta que usar json.loads simple y convertir recursivamente a str es probablemente más barato y quizás más rápido.

Con todo lo dicho, si quieres un loads que devuelve cadenas bastante mal aceptar ir a través de código que se extiende, que no estaba destinado a, aquí está uno de los resultados posibles (en su mayoría se extiende a través copia-n-goma) este se asnal, gracias Lennart por hacerme ver la luz (es decir, sólo tiene que extender JSONDecoder y un par de trucos):

import json 
from json import decoder, scanner 

from json.scanner import make_scanner 
from _json import scanstring as c_scanstring 

_CONSTANTS = json.decoder._CONSTANTS 

py_make_scanner = scanner.py_make_scanner 

# Convert from unicode to str 
def str_scanstring(*args, **kwargs): 
    result = c_scanstring(*args, **kwargs) 
    return str(result[0]), result[1] 

# Little dirty trick here 
json.decoder.scanstring = str_scanstring 

class StrJSONDecoder(decoder.JSONDecoder): 
    def __init__(self, encoding=None, object_hook=None, parse_float=None, 
      parse_int=None, parse_constant=None, strict=True, 
      object_pairs_hook=None): 
     self.encoding = encoding 
     self.object_hook = object_hook 
     self.object_pairs_hook = object_pairs_hook 
     self.parse_float = parse_float or float 
     self.parse_int = parse_int or int 
     self.parse_constant = parse_constant or _CONSTANTS.__getitem__ 
     self.strict = strict 
     self.parse_object = decoder.JSONObject 
     self.parse_array = decoder.JSONArray 
     self.parse_string = str_scanstring 
     self.scan_once = py_make_scanner(self) 

# And another little dirty trick there  
_default_decoder = StrJSONDecoder(encoding=None, object_hook=None, 
           object_pairs_hook=None) 

json._default_decoder = _default_decoder 

j = {1:'2', 1.1:[1,2,3], u'test': {12:12, 13:'o'}} 
print json.loads(json.dumps(j)) 
+0

Gracias por la respuesta detallada. Me doy cuenta ahora de que lo que quería no es compatible por una razón, así que me atengo a la solución str (unicode). – Adrian

+0

Lamento haberte asustado, Lennart me hizo darme cuenta de que es mucho más fácil obtener lo que querías. – TryPyPy