簡體   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