如何用Python打印JSON文件?


使用json.dump()或json.dumps()的indent关键字参数指定要使用的缩进量:

>>> 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
        ]
    }
]

要解析文件,请使用json.load():

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

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

python3 -m json.tool some.json

(正如问题评论中已经提到的,感谢@Kai Petzke提出的蟒蛇3建议)。

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

您也可以使用jq:

jq . some.json

你可以得到颜色作为奖励(而且更容易扩展)。

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


Pygmentize是为终端命令的输出着色的强大工具。

下面是一个使用它向json.tool输出添加语法高亮显示的示例:

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

结果如下:

在前面的堆栈溢出回答中,我详细介绍了如何安装和使用pygmentize。


使用这个函数,不用担心,你必须再次记住你的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 | jsonpp
jsonpp < myfile.json

使用json标准库模块读取数据后,使用pprint标准库模块显示解析的数据。例子:

import json
import pprint

json_data = None
with open('file_name.txt', 'r') as f:
    data = f.read()
    json_data = json.loads(data)

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;虽然它以良好的格式显示Python数据结构的内容,但它使用Python语法来实现。特别是,字符串(通常)用单引号括起来,而JSON需要双引号。要将数据重写为JSON文件,请使用pprint.pdf格式:

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 pprint
import json 
from urllib.request import urlopen # (Only used to get this example)

# Getting a JSON example for this example 
r = urlopen("https://mdn.github.io/fetch-examples/fetch-json/products.json")
text = r.read() 

# To print it
pprint.pprint(json.loads(text))

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

import pprint
pprint.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.text
    return json.dumps(parsed, ensure_ascii=True, indent=4)

您可以尝试pprintjson。


安装

$ pip3 install pprintjson

用法

使用pprintjson CLI从文件中精确打印JSON。

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

使用pprintjson CLI从stdin打印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))

TL;DR:在很多方面,也可以考虑打印(yaml.dump(j,sort_keys=False))

对于大多数用途,缩进应该做到:

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

Json结构基本上是树结构。当我试图找到一些更奇特的东西时,我偶然发现了这张漂亮的纸,上面描绘了其他形式的漂亮树木,可能很有趣:https://blog.ouseful.info/2021/07/13/exploring-the-hierarchical-structure-of-dataframes-and-csv-data/.

它有一些交互树,甚至还附带了一些代码,包括以下折叠树:

其他示例包括使用plotly以下是plotly的代码示例:

import plotly.express as px
fig = 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()

并使用treelib。注意,这个github还提供了很好的可视化效果。下面是一个使用treelib的示例:

#%pip install treelib
from treelib import Tree

country_tree = Tree()
# Create a root node
country_tree.create_node("Country", "countries")

# Group by country
for country, regions in wards_df.head(5).groupby(["CTRY17NM", "CTRY17CD"]):
    # Generate a node for each country
    country_tree.create_node(country[0], country[1], parent="countries")
    # Group by region
    for region, las in regions.groupby(["GOR10NM", "GOR10CD"]):
        # Generate a node for each region
        country_tree.create_node(region[0], region[1], parent=country[1])
        # Group by local authority
        for la, wards in las.groupby(['LAD17NM', 'LAD17CD']):
            # Create a node for each local authority
            country_tree.create_node(la[0], la[1], parent=region[1])
            for ward, _ in wards.groupby(['WD17NM', 'WD17CD']):
                # Create a leaf node for each ward
                country_tree.create_node(ward[0], ward[1], parent=la[1])

# Output the hierarchical data
country_tree.show()

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

from treelib import Node, Tree, node

def create_node(tree, s, counter_byref, verbose, parent_id=None):
    node_id = counter_byref[0]
    if verbose:
        print(f"tree.create_node({s}, {node_id}, parent={parent_id})")
    tree.create_node(s, node_id, parent=parent_id)
    counter_byref[0] += 1
    return node_id

def to_compact_string(o):
    if type(o) == dict:
        if len(o)>1:
            raise Exception()
        k,v =next(iter(o.items()))
        return f'{k}:{to_compact_string(v)}'
    elif type(o) == list:
        if len(o)>1:
            raise Exception()
        return f'[{to_compact_string(next(iter(o)))}]'
    else:
        return str(o)

def to_compact(tree, o, counter_byref, verbose, parent_id):
    try:
        s = to_compact_string(o)
        if verbose:
            print(f"# to_compact({o}) ==> [{s}]")
        create_node(tree, s, counter_byref, verbose, parent_id=parent_id)
        return True
    except:
        return False

def json_2_tree(o , parent_id=None, tree=None, counter_byref=[0], verbose=False, compact_single_dict=False, listsNodeSymbol='+'):
    if tree is None:
        tree = Tree()
        parent_id = create_node(tree, '+', counter_byref, verbose)
    if compact_single_dict and to_compact(tree, o, counter_byref, verbose, parent_id):
        # no need to do more, inserted as a single node
        pass
    elif type(o) == dict:
        for k,v in o.items():
            if compact_single_dict and to_compact(tree, {k:v}, counter_byref, verbose, parent_id):
                # no need to do more, inserted as a single node
                continue
            key_nd_id = create_node(tree, str(k), counter_byref, verbose, parent_id=parent_id)
            if verbose:
                print(f"# json_2_tree({v})")
            json_2_tree(v , parent_id=key_nd_id, tree=tree, counter_byref=counter_byref, verbose=verbose, listsNodeSymbol=listsNodeSymbol, compact_single_dict=compact_single_dict)
    elif type(o) == list:
        if listsNodeSymbol is not None:
            parent_id = create_node(tree, listsNodeSymbol, counter_byref, verbose, parent_id=parent_id)
        for i in o:
            if compact_single_dict and to_compact(tree, i, counter_byref, verbose, parent_id):
                # no need to do more, inserted as a single node
                continue
            if verbose:
                print(f"# json_2_tree({i})")
            json_2_tree(i , parent_id=parent_id, tree=tree, counter_byref=counter_byref, verbose=verbose,listsNodeSymbol=listsNodeSymbol, compact_single_dict=compact_single_dict)
    else: #node
        create_node(tree, str(o), counter_byref, verbose, parent_id=parent_id)
    return tree

例如:

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

给予:

+
├── 2
│   └── 3
├── 4
│   └── +
│       ├── 5
│       └── 6
└── 7
    └── 8
        └── 9

虽然

json_2_tree(j ,listsNodeSymbol=None, verbose=False ).show()  
+
├── 2
│   └── 3
├── 4
│   ├── 5
│   └── 6
└── 7
    └── 8
        └── 9

And

json_2_tree(j ,compact_single_dict=True,listsNodeSymbol=None).show() 
+
├── 2:3
├── 4
│   ├── 5
│   └── 6
└── 7:8:9

正如你所看到的,有不同的树,这取决于他想要的明确与紧凑程度。我最喜欢的一个,也是最紧凑的一个可能是使用yaml:

import yaml
j = json.loads('{"2": "3", "4": ["5", "6"], "7": {"8": "9"}}')
print(yaml.dump(j, sort_keys=False))

简洁明了:

'2': '3'
'4':
- '5'
- '6'
'7':
  '8': '9'

一个非常简单的方法是使用rich。使用此方法,您还可以突出显示json

此方法从名为config.json的json文件中读取数据

from rich import print_json

setup_type = open('config.json')
data = json.load(setup_type)
print_json(data=data)