1

オブジェクトをいつ展開するか、省略形のままにするかを知っているjsonエンコーダーを書きたいと思います。

私が持っているオブジェクトには多くのプロパティがあり、そのうちのいくつかは他のオブジェクトのコレクションです (コレクションである可能性のある独自のプロパティを無限に持っています)。このjson.dumpsメソッドは、すべてのオブジェクトを再帰する場合、非常に大きな文字列を返す可能性があります。

その深さの後に見つかったオブジェクトがそれ以上展開されないように「深さ」を設定することは可能ですか?

4

2 に答える 2

0

最も簡単なのは、辞書のコピーを作成し、コピーを好きなように編集してから、JSON ライブラリを使用してコピーを JSON エンコードすることだと思います。

辞書をコピーして特定のレベルで停止することは、次のような再帰関数を使用した非常に単純な問題です。

def is_dict(x):
    return hasattr(x, "has_key")

def dict_copy_n(d_to_copy, max_levels):
    assert max_levels >= 0
    d = {}
    for k, v in d_to_copy.items():
        if is_dict(v):
            if max_levels > 0:
                d[k] = dict_copy_n(v, max_levels - 1)
            else:
                # set key to None; or, delete the else: case to just ignore
                d[k] = None
        else:
            d[k] = v
    return d

上記のコードmax_levelsは、カウントダウンが 0 になるまですべてを変更せずにコピーします。0 になった時点で、値が a であるキーはコピー dict でdict単純に設定されます。None上記のコードを簡単に編集して、キーを他の値に設定したり、単にそのキーをコピーしないようにすることができます。

したがって、上記の関数を使用して元の部分的なコピーを作成し、そのコピーを JSON エンコードします。

于 2012-06-05T01:37:26.887 に答える
0

まず、ここで本当にハードディスクを節約できるかどうかを判断する必要があります。パーセント差で考えるのではなく、プログラムを実行する人々のディスクスペースのコストです。

次に、これを行うハックな方法を見つけました。

フォルダー /Lib/json/ を Python インストール以外のフォルダーにコピーします。フォルダに次のような名前を付けます。jsondepth

encoding.py に移動し、3 つの変更を行います (行番号は Python 2.7 のものです)。

411行目、変更

def _iterencode(o, _current_indent_level):
    if isinstance(o, basestring):
        yield _encoder(o)

def _iterencode(o, _current_indent_level):
    if(_current_indent_level > SKIP_INDENT_LEVEL):
        yield 'null'
        return
    if isinstance(o, basestring):
        yield _encoder(o)

行 335、変更

def _iterencode_dict(dct, _current_indent_level):
    if not dct:
        yield '{}'

def _iterencode_dict(dct, _current_indent_level):
    if(_current_indent_level > SKIP_INDENT_LEVEL):
        yield 'null'
        return
    if not dct:
        yield '{}'

行 282、変更

def _iterencode_list(lst, _current_indent_level):
    if not lst:
        yield '[]'

def _iterencode_list(lst, _current_indent_level):
    if(_current_indent_level > SKIP_INDENT_LEVEL):
        yield 'null'
        return
    if not lst:
        yield '[]'

5 行目、変更

try:
    from _json import encode_basestring_ascii as c_encode_basestring_ascii
except ImportError:
    c_encode_basestring_ascii = None
try:
    from _json import make_encoder as c_make_encoder
except ImportError:
    c_make_encoder = None

c_encode_basestring_ascii = None
c_make_encoder = None

ファイルの先頭のどこか (たとえば、13 行目)

SKIP_INDENT_LEVEL = 4 # or whatever recursion depth you want.

インデントを有効にする必要があることに注意してください。有効にしないと、これは完全に崩壊します。また、私はこれをテストしていないことに注意してください。明示または黙示の保証はありません:)

于 2012-06-05T00:46:05.360 に答える