2011-01-18 10 views
9

Ho un file di configurazione in JSON che contiene alcune variabili come stringhe (sempre ascii). Queste stringhe sono decodificate in Unicode per impostazione predefinita, ma dal momento che devo passare queste variabili alle mie estensioni Python C ho bisogno di loro come normali stringhe Python. Al momento sto usando str(unicode) per convertire le stringhe JSON ma una soluzione più elegante e meno verbosa sarebbe molto apprezzata.Come decodificare JSON in str e non unicode in Python (2.6)?

C'è un modo per modificare la traduzione predefinita da stringa a unicode con un oggetto personalizzato JSONDecoder o un hook dell'oggetto?

+0

Sì, un JSONDecoder personalizzato dovrebbe essere in grado di saltare la decodifica da STR a Unicode e restituisce la stringa binaria grezza. –

+0

@Lennart Regebro Ho provato a farlo e ho fallito: ho dovuto copiare-n-paste-estendere molte classi e costanti private del modulo. C'è un modo semplice per modificare JSONDecoder che non riesco a vedere? – TryPyPy

+0

@TryPyPy: non esistono costanti private del modulo in Python ... –

risposta

0

Vedere se le risposte a this question sono di aiuto (in questa domanda il richiedente stava utilizzando simplejson).

1

Non se non sei disposto a perdere velocità. Se essere un po 'più lento è OK, devi considerare che l'utilizzo di json.loads e la conversione in modo ricorsivo in str è probabilmente più economico e forse più veloce.

Con tutto quello che ha detto, se si vuole un loads che restituisce stringhe abbastanza male ad accettare passare attraverso il codice che si estende, che non doveva, ecco una possibile risultato (che si estende per lo più attraverso copia-n-incolla) questo è stato stupido, grazie Lennart per avermi fatto vedere la luce (per esempio, basta estendere JSONDecoder e un paio di trucchi):

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

Grazie per la risposta dettagliata. Mi rendo conto ora che ciò che volevo non è supportato per una ragione, quindi mi limiterò alla soluzione str (unicode). – Adrian

+0

Mi spiace di averti spaventato, Lennart mi ha fatto capire che è molto più facile ottenere ciò che volevi. – TryPyPy

Problemi correlati