簡體   English   中英

漂亮的打印 JSON 轉儲

[英]Pretty print JSON dumps

我使用此代碼將dict漂亮地打印到 JSON 中:

import json
d = {'a': 'blah', 'b': 'foo', 'c': [1,2,3]}
print json.dumps(d, indent = 2, separators=(',', ': '))

輸出:

{
  "a": "blah",
  "c": [
    1,
    2,
    3
  ],
  "b": "foo"
}

這有點太多了(每個列表元素的換行符!)。

我應該使用哪種語法來實現這個:

{
  "a": "blah",
  "c": [1, 2, 3],
  "b": "foo"
}

反而?

我最終使用了jsbeautifier

import jsbeautifier
opts = jsbeautifier.default_options()
opts.indent_size = 2
jsbeautifier.beautify(json.dumps(d), opts)

輸出:

{
  "a": "blah",
  "c": [1, 2, 3],
  "b": "foo"
}

編寫您自己的 JSON 序列化程序:

import numpy

INDENT = 3
SPACE = " "
NEWLINE = "\n"

def to_json(o, level=0):
    ret = ""
    if isinstance(o, dict):
        ret += "{" + NEWLINE
        comma = ""
        for k,v in o.iteritems():
            ret += comma
            comma = ",\n"
            ret += SPACE * INDENT * (level+1)
            ret += '"' + str(k) + '":' + SPACE
            ret += to_json(v, level + 1)

        ret += NEWLINE + SPACE * INDENT * level + "}"
    elif isinstance(o, basestring):
        ret += '"' + o + '"'
    elif isinstance(o, list):
        ret += "[" + ",".join([to_json(e, level+1) for e in o]) + "]"
    elif isinstance(o, bool):
        ret += "true" if o else "false"
    elif isinstance(o, int):
        ret += str(o)
    elif isinstance(o, float):
        ret += '%.7g' % o
    elif isinstance(o, numpy.ndarray) and numpy.issubdtype(o.dtype, numpy.integer):
        ret += "[" + ','.join(map(str, o.flatten().tolist())) + "]"
    elif isinstance(o, numpy.ndarray) and numpy.issubdtype(o.dtype, numpy.inexact):
        ret += "[" + ','.join(map(lambda x: '%.7g' % x, o.flatten().tolist())) + "]"
    else:
        raise TypeError("Unknown type '%s' for json serialization" % str(type(o)))
    return ret

inputJson = {'a': 'blah', 'b': 'foo', 'c': [1,2,3]}
print to_json(inputJson)

輸出:

{
   "a": "blah",
   "c": [1,2,3],
   "b": "foo"
}

另一種選擇是print(json.dumps(d, indent=None, separators=(',\\n', ': ')))

輸出將是:

{"a": "blah",
"c": [1,
2,
3],
"b": "foo"}

請注意,雖然https://docs.python.org/2.7/library/json.html#basic-usage 上的官方文檔說默認參數是separators=None --這實際上意味着“使用默認的separators=(', ',': ') ). 還要注意逗號分隔符不區分 k/v 對和列表元素。

多年后,我找到了內置pprint模塊的解決方案:

import pprint
d = {'a': 'blah', 'b': 'foo', 'c': [1,2,3]}
pprint.pprint(d)                    # default width=80 so this will be printed in a single line
pprint.pprint(d, width=20)          # here it will be wrapped exactly as expected

輸出:

{'a': 'blah',  
 'b': 'foo',  
 'c': [1, 2, 3]}

我無法讓 jsbeautifier 做很多事情,所以我使用了正則表達式。 有 json 模式,如

'{\n    "string": [\n        4,\n        1.0,\n        6,\n        1.0,\n        8,\n        1.0,\n        9,\n        1.0\n    ],\n...'

我想要的

'{\n    "string": [ 4, 1.0, 6, 1.0, 8, 1.0, 9, 1.0],\n'

所以

t = json.dumps(apriori, indent=4)
t = re.sub('\[\n {7}', '[', t)
t = re.sub('(?<!\]),\n {7}', ',', t)
t = re.sub('\n {4}\]', ']', t)
outfile.write(t)

因此,我有這 5 行,而不是一個“dump(apriori, t, indent=4)”。

這也困擾了我一段時間,我發現了一個我幾乎滿意的 1 班輪:

print json.dumps(eval(str(d).replace('[', '"[').replace(']', ']"').replace('(', '"(').replace(')', ')"')), indent=2).replace('\"\\"[', '[').replace(']\\"\"', ']').replace('\"\\"(', '(').replace(')\\"\"', ')')

這基本上將所有列表或元組轉換為字符串,然后使用帶有縮進的 json.dumps 來格式化字典。 然后你只需要刪除引號就完成了!

注意:無論 dict 是如何嵌套的,我都將 dict 轉換為字符串以輕松轉換所有列表/元組。

附注。 我希望 Python 警察不會因為我使用 eval 來找我...(小心使用)

也許效率不高,但考慮一個更簡單的情況(在 Python 3 中進行了一些測試,但可能也適用於 Python 2):

def dictJSONdumps( obj, levels, indentlevels = 0 ):
    import json
    if isinstance( obj, dict ):
        res = []
        for ix in sorted( obj, key=lambda x: str( x )):
            temp = ' ' * indentlevels + json.dumps( ix, ensure_ascii=False ) + ': '
            if levels:
                temp += dictJSONdumps( obj[ ix ], levels-1, indentlevels+1 )
            else:
                temp += json.dumps( obj[ ix ], ensure_ascii=False )
            res.append( temp )
        return '{\n' + ',\n'.join( res ) + '\n}'
    else:
        return json.dumps( obj, ensure_ascii=False )

除了完全編寫自己的序列化程序之外,這可能會給您一些想法。 我使用了我自己最喜歡的縮進技術,並硬編碼了 ensure_ascii,但是您可以添加參數並傳遞它們,或者對您自己的進行硬編碼等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM