In Python, have json not escape a string -
i caching json data, , in storage represented json-encode string. no work performed on json server before sending client, other collation of multiple cached objects, this:
def get_cached_items(): item1 = cache.get(1) item2 = cache.get(2) return json.dumps(item1=item1, item2=item2, msg="123")
there may other items included return value, in case represented msg="123"
.
the issue cached items double-escaped. behoove library allow pass-through of string without escaping it.
i have looked @ documentation json.dumps default
argument, seems place 1 address this, , searched on google/so found no useful results.
it unfortunate, performance perspective, if had decode json of each cached items send browser. unfortunate complexity perspective not able use json.dumps
.
my inclination write class stores cached string , when default
handler encounters instance of class uses string without perform escaping. have yet figure out how achieve though, , grateful thoughts , assistance.
edit clarity, here example of proposed default
technique:
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 # avoid call `encode_basestring` (or ascii equiv.) return super(jsonencoderwithraw, self).default(o)
here degenerate example of above:
>>> 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}"}'
the desired output include unescaped string m.str
, being:
'{"a": {"x": 123}}'
it if json module did not encode/escape return of default
parameter, or if same avoided. in absence of method via default
parameter, 1 may have achieve objective here overloading encode
, iterencode
method of jsonencoder
, brings challenges in terms of complexity, interoperability, , performance.
a quick-n-dirty way patch json.encoder.encode_basestring*()
functions:
import json class rawjson(unicode): pass # patch json.encoder module name in ['encode_basestring', 'encode_basestring_ascii']: def encode(o, _encode=getattr(json.encoder, name)): return o if isinstance(o, rawjson) else _encode(o) setattr(json.encoder, name, encode) print(json.dumps([1, rawjson(u'["abc", 2]'), u'["def", 3]'])) # -> [1, ["abc", 2], "[\"def\", 3]"]
Comments
Post a Comment