Sto memorizzando nella cache alcuni dati JSON e nella memoria è rappresentato come una stringa di codifica JSON. Nessun lavoro viene eseguito sul JSON dal server prima di inviarlo al cliente, oltre collazione di più oggetti memorizzati nella cache, in questo modo:In Python, json non sfugge a una stringa
def get_cached_items():
item1 = cache.get(1)
item2 = cache.get(2)
return json.dumps(item1=item1, item2=item2, msg="123")
Ci possono essere altri elementi inclusi con il valore di ritorno, in questo caso rappresentato di msg="123"
.
Il problema è che gli elementi memorizzati nella cache sono a doppio escape. Dovrebbe essere la libreria a consentire un pass-through della stringa senza sfuggirgli.
Ho esaminato la documentazione per json.dumps default
argument, poiché sembra essere il luogo in cui uno verrebbe indirizzato e cercato su google/SO ma non ha trovato risultati utili.
Sarebbe un peccato, dal punto di vista delle prestazioni, se dovessi decodificare il JSON di ogni elemento memorizzato nella cache per inviarlo al browser. Sarebbe sfortunato dal punto di vista della complessità non essere in grado di utilizzare json.dumps
.
La mia inclinazione è scrivere una classe che memorizza la stringa memorizzata nella cache e quando il gestore default
incontra un'istanza di questa classe, utilizza la stringa senza eseguire l'escape. Devo ancora capire come raggiungere questo obiettivo, e sarei grato per i pensieri e l'assistenza.
EDIT Per chiarezza, ecco un esempio della proposta default
tecnica:
class RawJSON(object):
def __init__(self, str):
self.str = str
class JSONEncoderWithRaw(json.JSONEncoder):
def default(self, o):
if isinstance(o, RawJSON):
return o.str # but avoid call to `encode_basestring` (or ASCII equiv.)
return super(JSONEncoderWithRaw, self).default(o)
Ecco un esempio degenerata di quanto sopra:
>>> class M():
str = ''
>>> m = M()
>>> m.str = json.dumps(dict(x=123))
>>> json.dumps(dict(a=m), default=lambda (o): o.str)
'{"a": "{\\"x\\": 123}"}'
L'uscita desiderato includerebbe l'escape stringa m.str
, essendo:
'{"a": {"x": 123}}'
Sarebbe bene se il modulo json non codificasse/fuggisse il ritorno del parametro default
, o se lo stesso potrebbe essere evitato. In assenza di un metodo tramite il parametro default
, potrebbe essere necessario raggiungere l'obiettivo in questo punto sovraccaricando il metodo encode
e iterencode
di JSONEncoder
, che presenta sfide in termini di complessità, interoperabilità e prestazioni.
Molto intelligente - lo adoro! –