繁体   English   中英

在Python中,让json不能转义字符串

[英]In Python, have json not escape a string

我正在缓存一些JSON数据,并且在存储中它表示为JSON编码字符串。 除了整理多个缓存对象之外,服务器在将JSON发送到客户端之前不会对JSON执行任何工作,如下所示:

def get_cached_items():
  item1 = cache.get(1)
  item2 = cache.get(2)
  return json.dumps(item1=item1, item2=item2, msg="123")

返回值中可能包含其他项,在这种情况下由msg="123"

问题是缓存的项目是双重转义的。 它应该是库允许字符串的传递而不转义它。

我查看了json.dumps default参数的文档,因为它似乎是一个人会解决这个问题的地方,并在google / SO上搜索但没有找到有用的结果。

从性能的角度来看,如果我必须解码每个缓存项目的JSON以将其发送到浏览器,那将是不幸的。 从复杂性的角度来看,不能使用json.dumps是不幸的。

我倾向于编写一个存储缓存字符串的类,当default处理程序遇到此类的实例时,它使用字符串而不执行转义。 我还没有弄清楚如何实现这一点,我将感激你的想法和帮助。

编辑为清楚起见,这里是建议的default技术的示例:

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)

以下是上述的退化示例:

>>> 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}"}'

所需的输出将包括未转义的字符串m.str ,其中:

'{"a": {"x": 123}}'

如果json模块没有编码/转义default参数的返回,或者如果可以避免相同,那将是很好的。 在没有通过方法的default参数,一个可能必须通过重载这里达到目的encodeiterencode的方法JSONEncoder ,其带来的复杂性,互操作性和性能方面的挑战。

一种快速的方法是修补json.encoder.encode_basestring*()函数:

import json

class RawJson(unicode):
    pass

# patch json.encoder module
for 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]"]

如果要缓存JSON字符串,则需要先将它们解码为python结构; json.dumps()无法区分正常字符串和真正JSON编码结构的字符串:

return json.dumps({'item1': json.loads(item1), 'item2': json.loads(item2), 'msg': "123"})

不幸的是,没有选择在此包含已经转换的JSON数据; default函数应该返回Python值。 您从传入的任何对象中提取数据并返回可以转换为JSON的值,而不是已经是JSON本身的值。

我能看到的唯一其他方法是插入“模板”值,然后使用字符串替换技术来操作JSON输出,以使用您的实际缓存数据替换模板:

json_data = json.dumps({'item1': '==item1==', 'item2': '==item2==', 'msg': "123"})
return json_data.replace('"==item1=="', item1).replace('"==item2=="', item2)

第三种选择是以非序列化形式缓存item1item2 ,作为Python结构而不是JSON字符串。

您可以使用维护simplejson好的simplejson而不是json来提供此功能。

import simplejson as json
from simplejson.encoder import RawJSON

print(json.dumps([1, RawJSON(u'["abc", 2]'), u'["def", 3]']))
# -> [1, ["abc", 2], "[\"def\", 3]"]

您可以获得简单的代码,以及simplejson所有C优化。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM