Hoe prachtigprint een JSON-bestand?

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 jsonMODULE implementeert al een beetje mooi afdrukken met de parameter indentdie 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 strof dictis – 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 pprintzoals 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.savemaar 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.

Other episodes