私はいくつかの 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
オーバーロードすることで目的を達成する必要がある場合があります。これは、複雑さ、相互運用性、およびパフォーマンスの面で課題をもたらします。encode
iterencode
JSONEncoder