如何漂亮地打印JSON文件?

如何在Python中漂亮地打印JSON文件?

1947057 次浏览

使用#1#2indent=参数来指定缩进多少个空格:

>>> import json>>>>>> your_json = '["foo", {"bar": ["baz", null, 1.0, 2]}]'>>> parsed = json.loads(your_json)>>> print(json.dumps(parsed, indent=4))["foo",{"bar": ["baz",null,1.0,2]}]

要解析文件,请使用#0

with open('filename.txt', 'r') as handle:parsed = json.load(handle)

您可以在命令行上执行此操作:

python3 -m json.tool some.json

(正如在问题的评论中已经提到的,感谢@KaiPetzke的python3建议)。

实际上,就命令行上的json处理而言,python并不是我最喜欢的工具。对于简单的漂亮打印来说是可以的,但是如果你想操作json,它可能会变得过于复杂。你很快就需要编写一个单独的脚本文件,你最终可能会得到键为u“一些键”(python Unicode)的映射,这使得选择字段更加困难,并且并不真正朝着漂亮打印的方向发展。

您也可以使用jq

jq . some.json

你会得到颜色作为奖励(并且更容易扩展)。

附录:关于一方面使用jq处理大JSON文件,另一方面使用非常大的jq程序的评论中有一些混淆。对于漂亮打印由单个大JSON实体组成的文件,实际限制是RAM。对于漂亮打印由单个现实世界数据数组组成的2GB文件,漂亮打印所需的“最大驻留集大小”是5GB(无论是使用jq 1.5还是1.6)。另请注意,jq可以在pip install jq之后从python中使用。

Pygmenze+Pythonjson.tool=带有语法高亮的漂亮打印

皮格门茨是一个杀手工具。看这个。

我把pythonjson.tool和pyg的结合起来

echo '{"foo": "bar"}' | python -m json.tool | pygmentize -l json

请参阅上面的链接以获取pyg的安装说明。

下面的图片中有一个演示:

demo

使用此函数,不必再次记住您的JSON是str还是dict-只需查看漂亮的打印:

import json
def pp_json(json_thing, sort=True, indents=4):if type(json_thing) is str:print(json.dumps(json.loads(json_thing), sort_keys=sort, indent=indents))else:print(json.dumps(json_thing, sort_keys=sort, indent=indents))return None
pp_json(your_json_string_or_dict)

为了能够从命令行漂亮地打印并能够控制缩进等,您可以设置类似于以下内容的别名:

alias jsonpp="python -c 'import sys, json; print json.dumps(json.load(sys.stdin), sort_keys=True, indent=2)'"

然后以以下方式之一使用别名:

cat myfile.json | jsonppjsonpp < myfile.json

您可以使用内置模块Pprint(https://docs.python.org/3.9/library/pprint.html)

如何使用json数据读取文件并将其打印出来。

import jsonimport pprint
json_data = Nonewith open('file_name.txt', 'r') as f:data = f.read()json_data = json.loads(data)
print(json_data){"firstName": "John", "lastName": "Smith", "isAlive": "true", "age": 27, "address": {"streetAddress": "21 2nd Street", "city": "New York", "state": "NY", "postalCode": "10021-3100"}, 'children': []}
pprint.pprint(json_data){'address': {'city': 'New York','postalCode': '10021-3100','state': 'NY','streetAddress': '21 2nd Street'},'age': 27,'children': [],'firstName': 'John','isAlive': True,'lastName': 'Smith'}

输出不是有效的json,因为pprint使用单引号,json规范需要双引号。

如果要将漂亮的print格式的json重写到文件中,则必须使用pprint.pformat

pretty_print_json = pprint.pformat(json_data).replace("'", '"')
with open('file_name.json', 'w') as f:f.write(pretty_print_json)

这里有一个简单的例子,用Python很好地将JSON打印到控制台,而不需要JSON作为本地文件在您的计算机上:

import pprintimport jsonfrom urllib.request import urlopen # (Only used to get this example)
# Getting a JSON example for this exampler = urlopen("https://mdn.github.io/fetch-examples/fetch-json/products.json")text = r.read()
# To print itpprint.pprint(json.loads(text))

使用pprint:https://docs.python.org/3.6/library/pprint.html

import pprintpprint.pprint(json)

print()pprint.pprint()相比

print(json){'feed': {'title': 'W3Schools Home Page', 'title_detail': {'type': 'text/plain', 'language': None, 'base': '', 'value': 'W3Schools Home Page'}, 'links': [{'rel': 'alternate', 'type': 'text/html', 'href': 'https://www.w3schools.com'}], 'link': 'https://www.w3schools.com', 'subtitle': 'Free web building tutorials', 'subtitle_detail': {'type': 'text/html', 'language': None, 'base': '', 'value': 'Free web building tutorials'}}, 'entries': [], 'bozo': 0, 'encoding': 'utf-8', 'version': 'rss20', 'namespaces': {}}
pprint.pprint(json){'bozo': 0,'encoding': 'utf-8','entries': [],'feed': {'link': 'https://www.w3schools.com','links': [{'href': 'https://www.w3schools.com','rel': 'alternate','type': 'text/html'}],'subtitle': 'Free web building tutorials','subtitle_detail': {'base': '','language': None,'type': 'text/html','value': 'Free web building tutorials'},'title': 'W3Schools Home Page','title_detail': {'base': '','language': None,'type': 'text/plain','value': 'W3Schools Home Page'}},'namespaces': {},'version': 'rss20'}

我认为最好先解析json,以避免错误:

def format_response(response):try:parsed = json.loads(response.text)except JSONDecodeError:return response.textreturn json.dumps(parsed, ensure_ascii=True, indent=4)

你可以试试p print json//请求参数//请求参数


安装

$ pip3 install pprintjson

用法

使用pprintjson CLI从文件中漂亮地打印JSON。

$ pprintjson "./path/to/file.json"

使用pprintjson CLI从标准输入中漂亮地打印JSON。

$ echo '{ "a": 1, "b": "string", "c": true }' | pprintjson

使用pprintjson CLI从字符串漂亮地打印JSON。

$ pprintjson -c '{ "a": 1, "b": "string", "c": true }'

从缩进为1的字符串漂亮地打印JSON。

$ pprintjson -c '{ "a": 1, "b": "string", "c": true }' -i 1

从字符串漂亮打印JSON并将输出保存到文件output.json.

$ pprintjson -c '{ "a": 1, "b": "string", "c": true }' -o ./output.json

产出

在此处输入图片描述

def saveJson(date,fileToSave):with open(fileToSave, 'w+') as fileToSave:json.dump(date, fileToSave, ensure_ascii=True, indent=4, sort_keys=True)

它的工作原理是将其显示或保存到文件中。

它远非完美,但它做的工作。

data = data.replace(',"',',\n"')

你可以改进它,添加缩进等等,但是如果你只是想能够阅读一个更干净的json,这就是要走的路。

我有一个类似的要求来转储json文件的内容以进行日志记录,一些快速而简单的事情:

print(json.dumps(json.load(open(os.path.join('<myPath>', '<myjson>'), "r")), indent = 4 ))

如果你经常使用它,那么把它放在一个函数中:

def pp_json_file(path, file):print(json.dumps(json.load(open(os.path.join(path, file), "r")), indent = 4))

希望这能帮助别人。

如果出现json不可序列化的错误,上述答案将不起作用。如果您只想保存它以便人类可读,那么您需要递归调用字典中所有非字典元素的字符串。如果您想稍后加载它,请将其保存为泡菜文件,然后加载它(例如torch.save(obj, f)正常工作)。

这是什么为我工作:

#%%
def _to_json_dict_with_strings(dictionary):"""Convert dict to dict with leafs only being strings. So it recursively makes keys to stringsif they are not dictionaries.
Use case:- saving dictionary of tensors (convert the tensors to strins!)- saving arguments from script (e.g. argparse) for it to be pretty
e.g.
"""if type(dictionary) != dict:return str(dictionary)d = {k: _to_json_dict_with_strings(v) for k, v in dictionary.items()}return d
def to_json(dic):import typesimport argparse
if type(dic) is dict:dic = dict(dic)else:dic = dic.__dict__return _to_json_dict_with_strings(dic)
def save_to_json_pretty(dic, path, mode='w', indent=4, sort_keys=True):import json
with open(path, mode) as f:json.dump(to_json(dic), f, indent=indent, sort_keys=sort_keys)
def my_pprint(dic):"""
@param dic:@return:
Note: this is not the same as pprint."""import json
# make all keys strings recursively with their naitve str functiondic = to_json(dic)# pretty printpretty_dic = json.dumps(dic, indent=4, sort_keys=True)print(pretty_dic)# print(json.dumps(dic, indent=4, sort_keys=True))# return pretty_dic
import torch# import json  # results in non serializabe errors for torch.Tensorsfrom pprint import pprint
dic = {'x': torch.randn(1, 3), 'rec': {'y': torch.randn(1, 3)}}
my_pprint(dic)pprint(dic)

输出:

{"rec": {"y": "tensor([[-0.3137,  0.3138,  1.2894]])"},"x": "tensor([[-1.5909,  0.0516, -1.5445]])"}{'rec': {'y': tensor([[-0.3137,  0.3138,  1.2894]])},'x': tensor([[-1.5909,  0.0516, -1.5445]])}

我不知道为什么返回字符串然后打印它不起作用,但似乎你必须将转储直接放在print语句中。注意pprint,因为它已经被建议也可以工作。注意不是所有的对象都可以转换为dict(dic)的字典,这就是为什么我的一些代码对此条件进行了检查。

背景:

我想保存pytorch字符串,但我一直收到错误:

TypeError: tensor is not JSON serializable

所以我编写了上面的代码。请注意,是的,在pytorch中您使用torch.save,但泡菜文件不可读。查看此相关帖子:https://discuss.pytorch.org/t/typeerror-tensor-is-not-json-serializable/36065/3


Pprint也有缩进参数,但我不喜欢它的外观:

    pprint(stats, indent=4, sort_dicts=True)

输出:

{   'cca': {   'all': {'avg': tensor(0.5132), 'std': tensor(0.1532)},'avg': tensor([0.5993, 0.5571, 0.4910, 0.4053]),'rep': {'avg': tensor(0.5491), 'std': tensor(0.0743)},'std': tensor([0.0316, 0.0368, 0.0910, 0.2490])},'cka': {   'all': {'avg': tensor(0.7885), 'std': tensor(0.3449)},'avg': tensor([1.0000, 0.9840, 0.9442, 0.2260]),'rep': {'avg': tensor(0.9761), 'std': tensor(0.0468)},'std': tensor([5.9043e-07, 2.9688e-02, 6.3634e-02, 2.1686e-01])},'cosine': {   'all': {'avg': tensor(0.5931), 'std': tensor(0.7158)},'avg': tensor([ 0.9825,  0.9001,  0.7909, -0.3012]),'rep': {'avg': tensor(0.8912), 'std': tensor(0.1571)},'std': tensor([0.0371, 0.1232, 0.1976, 0.9536])},'nes': {   'all': {'avg': tensor(0.6771), 'std': tensor(0.2891)},'avg': tensor([0.9326, 0.8038, 0.6852, 0.2867]),'rep': {'avg': tensor(0.8072), 'std': tensor(0.1596)},'std': tensor([0.0695, 0.1266, 0.1578, 0.2339])},'nes_output': {   'all': {'avg': None, 'std': None},'avg': tensor(0.2975),'rep': {'avg': None, 'std': None},'std': tensor(0.0945)},'query_loss': {   'all': {'avg': None, 'std': None},'avg': tensor(12.3746),'rep': {'avg': None, 'std': None},'std': tensor(13.7910)}}

比较:

{"cca": {"all": {"avg": "tensor(0.5144)","std": "tensor(0.1553)"},"avg": "tensor([0.6023, 0.5612, 0.4874, 0.4066])","rep": {"avg": "tensor(0.5503)","std": "tensor(0.0796)"},"std": "tensor([0.0285, 0.0367, 0.1004, 0.2493])"},"cka": {"all": {"avg": "tensor(0.7888)","std": "tensor(0.3444)"},"avg": "tensor([1.0000, 0.9840, 0.9439, 0.2271])","rep": {"avg": "tensor(0.9760)","std": "tensor(0.0468)"},"std": "tensor([5.7627e-07, 2.9689e-02, 6.3541e-02, 2.1684e-01])"},"cosine": {"all": {"avg": "tensor(0.5945)","std": "tensor(0.7146)"},"avg": "tensor([ 0.9825,  0.9001,  0.7907, -0.2953])","rep": {"avg": "tensor(0.8911)","std": "tensor(0.1571)"},"std": "tensor([0.0371, 0.1231, 0.1975, 0.9554])"},"nes": {"all": {"avg": "tensor(0.6773)","std": "tensor(0.2886)"},"avg": "tensor([0.9326, 0.8037, 0.6849, 0.2881])","rep": {"avg": "tensor(0.8070)","std": "tensor(0.1595)"},"std": "tensor([0.0695, 0.1265, 0.1576, 0.2341])"},"nes_output": {"all": {"avg": "None","std": "None"},"avg": "tensor(0.2976)","rep": {"avg": "None","std": "None"},"std": "tensor(0.0945)"},"query_loss": {"all": {"avg": "None","std": "None"},"avg": "tensor(12.3616)","rep": {"avg": "None","std": "None"},"std": "tensor(13.7976)"}}

json.loads()将json数据转换为字典。最后,使用json.dumps()漂亮地打印json。

_json = '{"name":"John", "age":30, "car":null}'
data = json.loads(_json)
print (json.dumps(data, indent=2))

对于大多数使用,indent应该这样做:

print(json.dumps(parsed, indent=2))

一个Json结构基本上是树形结构。在试图找到更花哨的东西时,我遇到了这篇漂亮的论文,描绘了其他形式的漂亮树,可能很有趣:https://blog.ouseful.info/2021/07/13/exploring-the-hierarchical-structure-of-dataframes-and-csv-data/

它有一些交互式树,甚至附带了一些代码,包括来自so的倒塌树输入图片描述

其他示例包括使用情节以下是ploly的代码示例:

import plotly.express as pxfig = px.treemap(names = ["Eve","Cain", "Seth", "Enos", "Noam", "Abel", "Awan", "Enoch", "Azura"],parents = ["", "Eve", "Eve", "Seth", "Seth", "Eve", "Eve", "Awan", "Eve"])fig.update_traces(root_color="lightgrey")fig.update_layout(margin = dict(t=50, l=25, r=25, b=25))fig.show()

输入图片描述输入图片描述

并使用树种。在这一点上,这个github还提供了很好的可视化。这是一个使用treelib的例子:

#%pip install treelibfrom treelib import Tree
country_tree = Tree()# Create a root nodecountry_tree.create_node("Country", "countries")
# Group by countryfor country, regions in wards_df.head(5).groupby(["CTRY17NM", "CTRY17CD"]):# Generate a node for each countrycountry_tree.create_node(country[0], country[1], parent="countries")# Group by regionfor region, las in regions.groupby(["GOR10NM", "GOR10CD"]):# Generate a node for each regioncountry_tree.create_node(region[0], region[1], parent=country[1])# Group by local authorityfor la, wards in las.groupby(['LAD17NM', 'LAD17CD']):# Create a node for each local authoritycountry_tree.create_node(la[0], la[1], parent=region[1])for ward, _ in wards.groupby(['WD17NM', 'WD17CD']):# Create a leaf node for each wardcountry_tree.create_node(ward[0], ward[1], parent=la[1])
# Output the hierarchical datacountry_tree.show()

输入图片描述

基于此,我创建了一个将json转换为树的函数:

from treelib import Node, Tree, nodedef json_2_tree(o , parent_id=None, tree=None, counter_byref=[0], verbose=False, listsNodeSymbol='+'):if tree is None:tree = Tree()root_id = counter_byref[0]if verbose:print(f"tree.create_node({'+'}, {root_id})")tree.create_node('+', root_id)counter_byref[0] += 1parent_id = root_idif type(o) == dict:for k,v in o.items():this_id = counter_byref[0]if verbose:print(f"tree.create_node({str(k)}, {this_id}, parent={parent_id})")tree.create_node(str(k), this_id, parent=parent_id)counter_byref[0]  += 1json_2_tree(v , parent_id=this_id, tree=tree, counter_byref=counter_byref, verbose=verbose, listsNodeSymbol=listsNodeSymbol)elif type(o) == list:if listsNodeSymbol is not None:if verbose:print(f"tree.create_node({listsNodeSymbol}, {counter_byref[0]}, parent={parent_id})")tree.create_node(listsNodeSymbol, counter_byref[0], parent=parent_id)parent_id=counter_byref[0]counter_byref[0]  += 1for i in o:json_2_tree(i , parent_id=parent_id, tree=tree, counter_byref=counter_byref, verbose=verbose,listsNodeSymbol=listsNodeSymbol)else: #nodeif verbose:print(f"tree.create_node({str(o)}, {counter_byref[0]}, parent={parent_id})")tree.create_node(str(o), counter_byref[0], parent=parent_id)counter_byref[0] += 1return tree

然后举个例子:

import jsonjson_2_tree(json.loads('{"2": 3, "4": [5, 6]}'),verbose=False,listsNodeSymbol='+').show()

给出了更具描述性的:

+├── 2│   └── 3└── 4└── +├── 5└── 6

虽然

json_2_tree(json.loads('{"2": 3, "4": [5, 6]}'),listsNodeSymbol=None).show()

提供更紧凑

+├── 2│   └── 3└── 4├── 5└── 6

对于不同口味的树木进行更广泛的转换,请查看此功能