Ik heb een JSON-bestand dat een puinhoop is die ik wil prettyprint. Wat is de eenvoudigste manier om dit in Python te doen?
Ik weet dat Prettrint een “object”, waarvan ik denk dat ik een bestand kan zijn, maar ik weet niet hoe ik een bestand moet passeren. Gewoon het gebruik van de bestandsnaam werkt niet.
Antwoord 1, Autoriteit 100%
De json
MODULE implementeert al een beetje mooi afdrukken met de parameter indent
die specificeert hoeveel ruimtes om in te schatten:
>>> 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
]
}
]
Gebruik json.load()
:
om een bestand te parseren
with open('filename.txt', 'r') as handle:
parsed = json.load(handle)
Antwoord 2, Autoriteit 18%
U kunt dit doen op de opdrachtregel:
python3 -m json.tool some.json
(Zoals reeds vermeld in de commentaar aan de vraag, dankzij @kai Petzke voor de Python3-suggestie).
Eigenlijk Python is niet mijn favoriete tool voor zover JSON-verwerking op de opdrachtregel betreft. Voor eenvoudige mooie afdrukken is OK, maar als je de JSON wilt manipuleren, kan het overweldigd raken. Je zou binnenkort een apart scriptbestand moeten schrijven, je zou kunnen eindigen met kaarten waarvan de sleutels je ‘sommigen’ ‘(Python Unicode) zijn, waardoor het selecteren van velden moeilijker is en niet echt in de richting van mooi gaat -printing.
U kunt ook JQ :
jq . some.json
En u krijgt kleuren als een bonus (en way eenvoudiger breiding).
Addendum: er is enige verwarring in de opmerkingen over het gebruik van JQ om grote JSON-bestanden enerzijds te verwerken en een zeer groot JQ-programma aan de andere kant te hebben. Voor mooi afdrukken van een bestand bestaande uit een enkele grote JSON-entiteit, is de praktische beperking RAM. Voor mooi afdrukken van een 2GB-bestand bestaande uit een enkele reeks van real-world-gegevens, was de “Maximale ingezetene ingestelde maat” die vereist is voor mooi afdrukken 5 GB (of het gebruik van JQ 1.5 of 1.6). Merk ook op dat JQ kan worden gebruikt vanuit Python na pip install jq
.
Antwoord 3, Autoriteit 4%
U kunt de ingebouwde module pprint (https: //docs.python .org / 3.9 / bibliotheek / pprint.html) .
Hoe u het bestand kunt lezen met JSON-gegevens en afdrukken.
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'}
De uitvoer is geen geldige json, omdat pprint enkele aanhalingstekens gebruikt en de json-specificatie dubbele aanhalingstekens vereist.
Antwoord 4, autoriteit 2%
Pygmentize + Python json.tool = Mooie afdruk met syntaxisaccentuering
Pygmentiseren is een geweldige tool. Zie dit.
Ik combineer python json.tool met pygmentize
echo '{"foo": "bar"}' | python -m json.tool | pygmentize -l json
Zie de link hierboven voor pygmentize installatie-instructies.
Een demo hiervan staat in de onderstaande afbeelding:
Antwoord 5, autoriteit 2%
Gebruik deze functie en maak je geen zorgen om te onthouden of je JSON opnieuw een str
of dict
is – kijk maar naar de mooie print:
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)
Antwoord 6
Gebruik Pprint: https://docs.python.org/3.6/Library/pprint .html
import pprint
pprint.pprint(json)
print()
vergeleken met 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'}
Antwoord 7
Om mooi te kunnen printen vanaf de opdrachtregel en controle te hebben over de inspringing enz. kun je een alias instellen die er ongeveer zo uitziet:
alias jsonpp="python -c 'import sys, json; print json.dumps(json.load(sys.stdin), sort_keys=True, indent=2)'"
En gebruik de alias dan op een van deze manieren:
cat myfile.json | jsonpp
jsonpp < myfile.json
Antwoord 8
Hier is een eenvoudig voorbeeld van het mooi afdrukken van JSON naar de console op een leuke manier in Python, zonder dat de JSON op je computer hoeft te staan als een lokaal bestand:
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))
Antwoord 9
def saveJson(date,fileToSave):
with open(fileToSave, 'w+') as fileToSave:
json.dump(date, fileToSave, ensure_ascii=True, indent=4, sort_keys=True)
Het werkt om het weer te geven of op te slaan in een bestand.
Antwoord 10
Je zou pprintjsonkunnen proberen.
Installatie
$ pip3 install pprintjson
Gebruik
Druk JSON mooi af vanuit een bestand met behulp van de pprintjson CLI.
$ pprintjson "./path/to/file.json"
Je kunt JSON mooi afdrukken vanaf een stdin met behulp van de pprintjson CLI.
$ echo '{ "a": 1, "b": "string", "c": true }' | pprintjson
Druk JSON mooi af vanuit een string met behulp van de pprintjson CLI.
$ pprintjson -c '{ "a": 1, "b": "string", "c": true }'
Prachtige JSON uit een tekenreeks met een inspringing van 1.
$ pprintjson -c '{ "a": 1, "b": "string", "c": true }' -i 1
Druk JSON mooi af vanuit een string en sla de uitvoer op in een bestand output.json.
$ pprintjson -c '{ "a": 1, "b": "string", "c": true }' -o ./output.json
Uitvoer
Antwoord 11
Ik denk dat het beter is om de json eerder te ontleden, om fouten te voorkomen:
def format_response(response):
try:
parsed = json.loads(response.text)
except JSONDecodeError:
return response.text
return json.dumps(parsed, ensure_ascii=True, indent=4)
Antwoord 12
Ik had een vergelijkbare vereiste om de inhoud van het json-bestand te dumpen voor logboekregistratie, iets snel en gemakkelijk:
print(json.dumps(json.load(open(os.path.join('<myPath>', '<myjson>'), "r")), indent = 4 ))
als je het vaak gebruikt, plaats het dan in een functie:
def pp_json_file(path, file):
print(json.dumps(json.load(open(os.path.join(path, file), "r")), indent = 4))
Antwoord 13
Hopelijk helpt dit iemand anders.
In het geval dat er een fout is dat iets niet json serialiseerbaar is, zullen de bovenstaande antwoorden niet werken. Als je het alleen wilt opslaan zodat het leesbaar is voor mensen, dan moet je de string recursief aanroepen op alle niet-woordenboekelementen van je woordenboek. Als je het later wilt laden, sla het dan op als een augurk-bestand en laad het vervolgens (bijv. torch.save(obj, f)
werkt prima).
Dit is wat voor mij werkte:
#%%
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)
uitvoer:
{
"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]])}
Ik weet niet waarom het retourneren van de string en vervolgens afdrukken niet werkt, maar het lijkt erop dat je de dumps rechtstreeks in de print-instructie moet plaatsen. Opmerking pprint
zoals het is voorgesteld, werkt ook al. Merk op dat niet alle objecten kunnen worden geconverteerd naar een dictaat met dict(dic)
, daarom heeft een deel van mijn code controles op deze voorwaarde.
Context:
Ik wilde pytorch-strings opslaan, maar ik kreeg steeds de foutmelding:
TypeError: tensor is not JSON serializable
dus ik heb het bovenstaande gecodeerd. Merk op dat ja, in pytorch gebruik je torch.save
maar pickle-bestanden zijn niet leesbaar. Bekijk dit gerelateerde bericht: https://discuss .pytorch.org/t/typeerror-tensor-is-not-json-serializable/36065/3
PPrint heeft ook inspringingsargumenten, maar ik vond het er niet leuk uitzien:
pprint(stats, indent=4, sort_dicts=True)
uitvoer:
{ '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)}}
Vergelijk met:
{
"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)"
}
}
Antwoord 14
Het is verre van perfect, maar het doet zijn werk.
data = data.replace(',"',',\n"')
je kunt het verbeteren, inspringen toevoegen enzovoort, maar als je gewoon een schonere json wilt kunnen lezen, is dit de juiste keuze.