5

私はいくつかの 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.dumpsdefault引数のドキュメントを調べました。これは、これに対処する場所のようであり、google/SO で検索しましたが、有用な結果が見つかりませんでした。

キャッシュされた各項目の JSON をデコードしてブラウザーに送信する必要があるとしたら、パフォーマンスの観点からは残念です。を使用できないのは、複雑さの観点から残念なことjson.dumpsです。

私の傾向は、キャッシュされた文字列を格納するクラスを作成することですdefault。ハンドラーがこのクラスのインスタンスに遭遇すると、エスケープを実行せずに文字列を使用します。ただし、これを達成する方法はまだわかっていません。考えと支援に感謝します。

EDITわかりやすくするために、提案された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パラメーターの戻り値をエンコード/エスケープしない場合、または同じことを回避できる場合は良いでしょう。パラメータを介したメソッドがない場合、のandメソッドをdefaultオーバーロードすることで目的を達成する必要がある場合があります。これは、複雑さ、相互運用性、およびパフォーマンスの面で課題をもたらします。encodeiterencodeJSONEncoder

4

3 に答える 3

2

この機能を提供する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]"]

コードの簡素化に加えて、 のすべての C 最適化が得られsimplejsonます。

于 2017-07-04T23:19:56.220 に答える