Come stampare piuttosto un file JSON?


1060

Ho un file JSON che è un casino che voglio stampare piuttosto-- qual è il modo più semplice per farlo in Python? So che PrettyPrint prende un "oggetto", che penso possa essere un file, ma non so come passare un file, semplicemente usando il nome del file non funziona.


9
Prova ad analizzare JSON usando json.loads()e piuttosto stampa quel dizionario risultante. Oppure passa direttamente alla sezione Stampa graziosa della documentazione dijson Python per .
Blender,


1
@Blender se pubblichi una risposta ti darò credito ... questo potrebbe chiudersi come duplicato, perché la soluzione è la stessa, ma la domanda è diversa, quindi forse no.
Colleen,

18
perché non <your_file.js python -mjson.toolcome nel link di @ ed?
jfs,

11
Non penso sia duplicato perché la stampa carina dalla riga di comando non è la stessa della stampa carina a livello di codice da Python. Votazione per riaprire.
vitaut,

Risposte:


1664

Il jsonmodulo implementa già alcune semplici stampe di base con il indentparametro:

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

Per analizzare un file, utilizzare json.load():

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

143
Per una semplice stampa, funziona anche senza analisi esplicita:print json.dumps(your_json_string, indent=4)
Peterino,

1
cosa fa il trattino?
timbram,

8
@timbram: è il numero di spazi per rientrare.
Blender,

9
Senza il rientro, ottieni solo una riga di brutto testo, motivo per cui sono venuto qui.
krs013

6
@Peterino Prima ho dovuto analizzare la stringa JSON: print(json.dumps(json.loads(your_json_string), indent=2))altrimenti mi ha mostrato una stringa sfuggita
Vladkras

310

Puoi farlo dalla riga di comando:

python3 -m json.tool some.json

(come già menzionato nei commenti alla domanda, grazie a @Kai Petzke per il suggerimento di python3).

In realtà python non è il mio strumento preferito per quanto riguarda l'elaborazione json sulla riga di comando. Per una stampa piuttosto carina è ok, ma se si desidera manipolare il json può complicarsi eccessivamente. Avresti presto bisogno di scrivere un file di script separato, potresti finire con mappe le cui chiavi sono "a qualche tasto" (python unicode), il che rende più difficile la selezione dei campi e non va nella direzione di pretty -stampa.

Puoi anche usare jq :

jq . some.json

e ottieni i colori come bonus (e in modo molto più semplice estensibilità).

Addendum: c'è qualche confusione nei commenti sull'uso di jq per elaborare file JSON di grandi dimensioni da un lato e sull'avere un programma jq molto grande. Per stampare piuttosto un file costituito da un'unica entità JSON di grandi dimensioni, il limite pratico è la RAM. Per la stampa carina di un file da 2 GB costituito da un singolo array di dati del mondo reale, la "dimensione massima impostata per residenti" richiesta per la stampa carina era di 5 GB (se si utilizza jq 1.5 o 1.6). Nota anche che jq può essere usato da Python dopo pip install jq.


4
JQ è eccezionale, ma esiste un limite massimo, quindi è inutile per file di grandi dimensioni. (ovvero esplode gestendo un file 1.15mb) github.com/stedolan/jq/issues/1041
Chris McKee,

3
sì, amico, sicuramente, se stai scrivendo filtri jq con più di 10K righe di codice, penso che stai provando qualcosa come andare su Marte con una bicicletta.
Gismo Ranas,

2
lol: D @ gismo-ranas La versione json.tool reindirizzata a un file funziona davvero molto bene su file di grandi dimensioni; ed è stupidamente veloce. Mi piace JQ ma la formattazione di qualsiasi cosa oltre un piccolo payload (cosa che potresti fare nella maggior parte degli editor di testo) è fuori dalla sua portata :) Aggiunta casuale: json-generator.com è uno strumento accurato per rendere i dati di test
Chris McKee

5
o semplicemente:jq '' < some.json
fatal_error

2
In realtà consiglio vivamente di usare python3 -m json.tool <IN >OUT, in quanto mantiene l'ordine originale dei campi in dicts JSON. La versione 2 dell'interprete Python ordina i campi in ordine alfabetico crescente, che spesso non è quello che desideri.
Kai Petzke,

55

È possibile utilizzare la modul pprint integrata (https://docs.python.org/3.6/library/pprint.html) .

Come leggere il file con i dati json e stamparlo.

import json
import pprint

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

pprint.pprint(json_data)

4
Il problema è che pprint userà le virgolette singole e doppie in modo intercambiabile, ma json richiede solo virgolette doppie, quindi il tuo json stampato non può più analizzare come json valido.
drevicko,

1
Sì, ma serve solo per generare un file json. Non prendere l'output e scriverlo di nuovo in un file.
Ikreb,

52

Pygmentize + Python json.tool = Pretty Print con evidenziazione della sintassi

Pygmentize è uno strumento killer. Guarda questo.

Combino python json.tool con pygmentize

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

Vedere il link sopra per le istruzioni di installazione di pygmentize.

Una demo di questo è nell'immagine qui sotto:

dimostrazione


1
Nel tuo esempio in -grealtà non funziona;) Poiché l'input proviene da stdin, pygmentize non è in grado di fare una buona ipotesi. Devi specificare esplicitamente lexer:echo '{"foo": "bar"}' | python -m json.tool | pygmentize -l json
Denis The Menace

1
@DenisTheMenace Funzionava nel 2015 quando ho creato questa immagine di esempio. Non sembra funzionare ora anche sul mio sistema.
Shubham Chaudhary,

36

Usa questa funzione e non preoccuparti di dover ricordare se il tuo JSON è stro di dictnuovo - guarda la bella stampa:

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)

14

Una volta ho scritto una prettyjson()funzione per produrre output di bell'aspetto. È possibile acquisire l'implementazione da questo repository .

La caratteristica principale di questa funzione è che cerca di mantenere la dettatura e di elencare gli elementi in una riga fino a quando non ne è certo maxlinelength viene raggiunto . Questo produce meno righe di JSON, l'output appare più compatto e più facile da leggere.

È possibile produrre questo tipo di output, ad esempio:

{
  "grid": {"port": "COM5"},
  "policy": {
    "movingaverage": 5,
    "hysteresis": 5,
    "fan1": {
      "name": "CPU",
      "signal": "cpu",
      "mode": "auto",
      "speed": 100,
      "curve": [[0, 75], [50, 75], [75, 100]]
    }
}

UPD dic. 19: ho inserito il codice in un repository separato , corretto alcuni bug e apportato alcune altre modifiche.


Ritengo che questo formattatore sia il migliore tra quelli suggeriti, merita più voti.
thorhunter,

13

Per poter stampare piuttosto dalla riga di comando ed avere il controllo sul rientro ecc., Puoi impostare un alias simile a questo:

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

E quindi usa l'alias in uno di questi modi:

cat myfile.json | jsonpp
jsonpp < myfile.json

11

Usa pprint: https://docs.python.org/3.6/library/pprint.html

import pprint
pprint.pprint(json)

print() rispetto a 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'}

pprintnon produce un documento JSON valido.
selurvedu,

5

Ecco un semplice esempio di una bella stampa di JSON sulla console in un bel modo in Python, senza richiedere che JSON sia sul tuo computer come file locale:

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))

Ricevo il seguente messaggio di errore in Python 3: "TypeError: l'oggetto JSON deve essere str, non 'bytes'"
Mr. T

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

Funziona per visualizzarlo o salvarlo in un file.


1

Penso che sia meglio analizzare il json prima, per evitare errori:

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

1

Potresti provare pprintjson .


Installazione

$ pip3 install pprintjson

uso

Stampa piuttosto JSON da un file utilizzando l'interfaccia della riga di comando di pprintjson.

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

Stampa piuttosto JSON da uno stdin usando l'interfaccia della riga di comando pprintjson.

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

Stampa piuttosto JSON da una stringa utilizzando l'interfaccia della riga di comando di pprintjson.

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

Stampa piuttosto JSON da una stringa con un rientro di 1.

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

Stampa piuttosto JSON da una stringa e salva l'output in un file output.json.

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

Produzione

inserisci qui la descrizione dell'immagine


0

È tutt'altro che perfetto, ma fa il lavoro.

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

puoi migliorarlo, aggiungere rientri e così via, ma se vuoi solo essere in grado di leggere un json più pulito, questa è la strada da percorrere.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.