Python 不同“深度”的不同json编码器

Python 不同“深度”的不同json编码器,python,json,Python,Json,我想编写一个json编码器,它知道什么时候扩展对象,或者以缩写形式保留对象 我拥有的对象有很多属性,其中一些是其他对象的集合,这些对象又有自己的属性,这些属性可能是集合,无限大。如果json.dumps方法在所有对象中递归,它可能返回非常大的字符串 是否可以设置一个深度,以便在该深度之后找到的任何对象都不会进一步扩展?首先,您应该弄清楚您是否真的在这里节省了硬盘空间。不要考虑百分比差异,而是运行程序的人员磁盘空间的美元成本 其次,我想出了一个简单的方法: 将文件夹/Lib/json/复制到pyt

我想编写一个json编码器,它知道什么时候扩展对象,或者以缩写形式保留对象

我拥有的对象有很多属性,其中一些是其他对象的集合,这些对象又有自己的属性,这些属性可能是集合,无限大。如果json.dumps方法在所有对象中递归,它可能返回非常大的字符串


是否可以设置一个深度,以便在该深度之后找到的任何对象都不会进一步扩展?

首先,您应该弄清楚您是否真的在这里节省了硬盘空间。不要考虑百分比差异,而是运行程序的人员磁盘空间的美元成本

其次,我想出了一个简单的方法:

将文件夹/Lib/json/复制到python安装之外的文件夹中。将文件夹命名为jsondepth

转到encoder.py并对Python 2.7中的行号进行3个更改:

第411行,更改

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

第335行,更改

def _iterencode_dict(dct, _current_indent_level):
    if not dct:
        yield '{}'
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

第282行,更改

def _iterencode_list(lst, _current_indent_level):
    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

在文件顶部的某个地方,比如第13行

SKIP_INDENT_LEVEL = 4 # or whatever recursion depth you want.

请注意,必须启用缩进,否则将完全崩溃。还要注意,我没有测试这个。没有明示或暗示的保证:

我认为最简单的方法就是复制您的dict,根据您的喜好编辑副本,然后使用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为止,此时值为dict的任何键都将在复制dict中简单地设置为None。您可以轻松编辑上面的代码以将该键设置为其他值,或者简单地不复制该键


因此,使用上述函数制作原始文件的部分副本,然后对副本进行JSON编码。

您认为未解码部分会发生什么情况?我可以提供REPROBJ,这非常大胆,只需修改JSON编码器即可。但是这个解决方案硬编码了最大深度,我不喜欢。我更喜欢将代码放在项目中,而不必通过破解Python安装来运行代码。我假设您担心的是其他使用json包的应用程序将无法工作;我担心您需要将修改后的JSON编码器文件放在/usr/lib子目录树或Windows上的等效目录树中。但我犯了一个愚蠢的错误。当然,您可以将JSON编码器文件复制到项目目录中;仅仅因为它来自Python库目录并不意味着您必须将它留在那里。很抱歉。
c_encode_basestring_ascii = None
c_make_encoder = None
SKIP_INDENT_LEVEL = 4 # or whatever recursion depth you want.
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