我有一个 JSON 文件,我想把它弄得一团糟。在 Python 中最简单的方法是什么?
我知道 PrettyPrint 需要一个“对象”,我认为它可以是一个文件,但我不知道如何传入文件。仅使用文件名是行不通的。
我有一个 JSON 文件,我想把它弄得一团糟。在 Python 中最简单的方法是什么?
我知道 PrettyPrint 需要一个“对象”,我认为它可以是一个文件,但我不知道如何传入文件。仅使用文件名是行不通的。
该json
模块dump
已经在anddumps
函数中实现了一些基本的漂亮打印,indent
参数指定要缩进多少个空格:
>>> import json
>>>
>>> your_json = '["foo", {"bar":["baz", null, 1.0, 2]}]'
>>> parsed = json.loads(your_json)
>>> print(json.dumps(parsed, indent=4, sort_keys=True))
[
"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 的python3 建议)。
实际上,就命令行上的 json 处理而言,python 并不是我最喜欢的工具。对于简单漂亮的打印是可以的,但如果你想操纵 json 它可能会变得过于复杂。您很快就需要编写一个单独的脚本文件,您最终可能会得到键为 u"some-key" (python unicode) 的映射,这使得选择字段更加困难,并且并没有真正朝着漂亮的方向发展-印刷。
您还可以使用jq:
jq . some.json
并且您可以获得颜色作为奖励(并且更容易扩展)。
附录:一方面关于使用 jq 处理大型 JSON 文件,另一方面有一个非常大的 jq 程序的评论中存在一些混淆。为了漂亮地打印由单个大型 JSON 实体组成的文件,实际限制是 RAM。对于包含单个真实数据数组的 2GB 文件的漂亮打印,漂亮打印所需的“最大驻留集大小”为 5GB(无论使用 jq 1.5 还是 1.6)。还要注意 jq 可以在 python 之后使用pip install jq
。
您可以使用内置模块pprint (https://docs.python.org/3.9/library/pprint.html)。
如何使用 json 数据读取文件并将其打印出来。
import json
import pprint
json_data = None
with 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 规范需要双引号。
如果要将漂亮打印格式的 json 重写为文件,则必须使用pprint.pformat。
pretty_print_json = pprint.pformat(json_data).replace("'", '"')
with open('file_name.json', 'w') as f:
f.write(pretty_print_json)
Pygmentize 是一个杀手级工具。看到这个。
我将 python json.tool 与 pygmentize 结合使用
echo '{"foo": "bar"}' | python -m json.tool | pygmentize -l json
有关 pygmentize 安装说明,请参见上面的链接。
下图是一个演示:
使用这个函数,不必费力记住你的 JSON 是 astr
还是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)
使用 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'}
为了能够从命令行漂亮地打印并能够控制缩进等,您可以设置类似于以下的别名:
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
这是一个简单的示例,它在 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))
def saveJson(date,fileToSave):
with open(fileToSave, 'w+') as fileToSave:
json.dump(date, fileToSave, ensure_ascii=True, indent=4, sort_keys=True)
它可以显示或保存到文件中。
你可以试试pprintjson。
$ 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
我认为最好先解析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)
我有一个类似的要求来转储 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 strings
if 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 types
import 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 function
dic = to_json(dic)
# pretty print
pretty_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.Tensors
from 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]])}
我不知道为什么返回字符串然后打印它不起作用,但似乎你必须将转储直接放在打印语句中。请注意pprint
,因为它已经被建议已经工作了。请注意,并非所有对象都可以转换为 dict ,dict(dic)
这就是为什么我的一些代码会检查这种情况。
语境:
我想保存 pytorch 字符串,但我一直收到错误消息:
TypeError: tensor is not JSON serializable
所以我对上面进行了编码。请注意,是的,在您使用的 pytorch 中,torch.save
pickle 文件不可读。检查此相关帖子: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)"
}
}
它远非完美,但它可以完成工作。
data = data.replace(',"',',\n"')
你可以改进它,添加缩进等等,但如果你只是想能够读取更干净的 json,这就是要走的路。