Como imprimir um arquivo JSON?

1060

Eu tenho um arquivo JSON que é uma bagunça que eu quero imprimir - qual é a maneira mais fácil de fazer isso em python? Eu sei que o PrettyPrint pega um "objeto", que eu acho que pode ser um arquivo, mas não sei como passar um arquivo - apenas usar o nome do arquivo não funciona.

Colleen
fonte
9
Tente analisar o JSON usando json.loads()e imprima esse dicionário resultante. Ou simplesmente pule para a seção Impressão bonita da documentaçãojson do Python para .
Blender
1
@ Blender, se você postar uma resposta, eu lhe darei crédito ... isso pode ser fechado como duplicado, porque a solução é a mesma, mas a pergunta é diferente, talvez não.
Colleen
18
por que não <your_file.js python -mjson.toolcomo no link do @ ed?
JFS
11
Não acho que seja duplicado, porque imprimir bonito a partir da linha de comando não é o mesmo que imprimir bonito programaticamente no Python. Votação para reabrir.
vitaut 16/09/2015

Respostas:

1663

O jsonmódulo já implementa algumas impressões bonitas básicas com o indentparâmetro:

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

Para analisar um arquivo, use json.load():

with open('filename.txt', 'r') as handle:
    parsed = json.load(handle)
Liquidificador
fonte
143
Para simples impressão bonita isso também funciona sem análise explícita:print json.dumps(your_json_string, indent=4)
Peterino
1
o que o travessão faz?
timbram
8
@timbram: É o número de espaços para recuar.
Blender
9
Sem o recuo, você apenas recebe uma única linha de texto feio, e é por isso que eu vim aqui.
krs013
6
@Peterino eu tive que analisar string JSON primeiro: print(json.dumps(json.loads(your_json_string), indent=2))caso contrário, apenas me mostrou uma string escapou
vladkras
310

Você pode fazer isso na linha de comando:

python3 -m json.tool some.json

(como já mencionado nos comentários da pergunta, obrigado a @Kai Petzke pela sugestão de python3).

Na verdade, python não é minha ferramenta favorita no que diz respeito ao processamento json na linha de comando. Para uma impressão bonita e simples, tudo bem, mas se você quiser manipular o json, pode ficar complicado demais. Em breve, você precisará escrever um arquivo de script separado; poderá acabar com mapas cujas chaves são u "some-key" (python unicode), o que torna a seleção de campos mais difícil e realmente não vai na direção de -impressão.

Você também pode usar jq :

jq . some.json

e você obtém cores como um bônus (e muito mais fácil de expandir).

Adendo: Há alguma confusão nos comentários sobre o uso de jq para processar arquivos JSON grandes, por um lado, e a existência de um programa jq muito grande, por outro. Para imprimir bonito um arquivo que consiste em uma única entidade JSON grande, a limitação prática é a RAM. Para imprimir bonito um arquivo de 2 GB que consiste em uma única matriz de dados do mundo real, o "tamanho máximo do conjunto de residentes" necessário para a impressão bonita era de 5 GB (seja usando jq 1.5 ou 1.6). Observe também que o jq pode ser usado no python depois pip install jq.

Gismo Ranas
fonte
4
O JQ é ótimo, mas há um limite máximo, portanto é inútil para arquivos grandes. (isto é, explode ao manipular um arquivo de 1.15mb) github.com/stedolan/jq/issues/1041
Chris McKee
3
Sim, definitivamente, se você estiver escrevendo filtros jq com mais de 10 mil linhas de código, acho que você está tentando algo como ir a Marte com uma bicicleta.
Gismo Ranas
2
lol: D @ gismo-ranas A versão do json.tool canalizada para um arquivo funciona realmente muito bem em arquivos grandes; e é estupidamente rápido. I como JQ mas formatação nada além de uma pequena carga útil (que você poderia fazer na maioria dos editores de texto) está além de sua adição alcance :) aleatória: json-generator.com é uma ferramenta pura para tornar os dados de teste
Chris McKee
5
ou apenas:jq '' < some.json
fatal_error
2
Na verdade, eu recomendo o uso python3 -m json.tool <IN >OUT, pois isso mantém a ordem original dos campos nos dicionários JSON. O interpretador python versão 2 classifica os campos em ordem alfabética crescente, o que geralmente não é o que você deseja.
Kai Petzke 20/01/19
55

Você pode usar o módulo interno pprint (https://docs.python.org/3.6/library/pprint.html) .

Como você pode ler o arquivo com dados json e imprimi-lo.

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)
ikreb
fonte
4
O problema é que o pprint usará aspas simples e duplas de forma intercambiável, mas o json requer apenas aspas duplas, portanto, o json pprinted pode não mais analisar como json válido.
drevicko
1
Sim, mas é apenas para gerar um arquivo json. Não pegue a saída e escreva-a novamente em um arquivo.
Ikreb
52

Pycementize + Python json.tool = Impressão bonita com destaque de sintaxe

Pycementize é uma ferramenta matadora. Veja isso.

Combino python json.tool com pycementize

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

Consulte o link acima para obter instruções de instalação de pycementize.

Uma demonstração disso está na imagem abaixo:

demonstração

Shubham Chaudhary
fonte
1
No seu exemplo -gnão está realmente funcionando;) Como a entrada vem do stdin, o pycementize não é capaz de dar um bom palpite. Você precisa especificar explicitamente o lexer:echo '{"foo": "bar"}' | python -m json.tool | pygmentize -l json
Denis The Menace
1
@DenisTheMenace Costumava funcionar em 2015 quando criei esta imagem de exemplo. Parece não estar funcionando agora no meu sistema também.
Shubham Chaudhary
36

Use esta função e não se preocupe, lembrando se o seu JSON é uma strou dictoutra vez - basta olhar para a bonita estampa:

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)
zelusp
fonte
14

Certa vez, escrevi uma prettyjson()função para produzir uma saída bonita. Você pode pegar a implementação neste repositório .

A principal característica dessa função é tentar manter o ditado e listar os itens em uma linha até que um certo maxlinelengthseja alcançado. Isso produz menos linhas de JSON, a saída parece mais compacta e fácil de ler.

Você pode produzir esse tipo de saída, por exemplo:

{
  "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 Dez'19: Coloquei o código em um repositório separado , corrigi alguns bugs e fiz alguns outros ajustes.

Andy
fonte
Considero que este formatador é o melhor dos sugeridos, merece mais votos.
thorhunter 16/10/19
13

Para poder imprimir da linha de comando e ter controle sobre o recuo, etc., você pode configurar um alias semelhante a este:

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

E, em seguida, use o alias de uma destas maneiras:

cat myfile.json | jsonpp
jsonpp < myfile.json
VP
fonte
11

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

import pprint
pprint.pprint(json)

print() comparado com 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'}
Nakamoto
fonte
pprintnão produz um documento JSON válido.
Selurvedu 26/11/19
5

Aqui está um exemplo simples de impressão bonita de JSON no console de uma maneira agradável em Python, sem exigir que o JSON esteja no seu computador como um arquivo local:

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))
David Liu
fonte
Recebo a seguinte mensagem de erro no Python 3: "TypeError: o objeto JSON deve ser str, não 'bytes'"
Sr. T
3
def saveJson(date,fileToSave):
    with open(fileToSave, 'w+') as fileToSave:
        json.dump(date, fileToSave, ensure_ascii=True, indent=4, sort_keys=True)

Ele funciona para exibi-lo ou salvá-lo em um arquivo.

Pablo Emmanuel De Leo
fonte
1

Eu acho que é melhor analisar o json antes, para evitar erros:

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

Você pode tentar pprintjson .


Instalação

$ pip3 install pprintjson

Uso

Imprima JSON de um arquivo usando a CLI pprintjson.

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

Imprima JSON a partir de um stdin usando a CLI pprintjson.

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

Imprima JSON a partir de uma string usando a CLI pprintjson.

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

JSON bonito da impressão de uma corda com um recuo de 1.

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

Imprima JSON a partir de uma string e salve a saída em um arquivo output.json.

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

Resultado

insira a descrição da imagem aqui

Travis Clarke
fonte
0

Está longe de ser perfeito, mas faz o trabalho.

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

você pode aprimorá-lo, adicionar recuo e assim por diante, mas se você quiser apenas ler um json mais limpo, esse é o caminho a seguir.

Francisco Perdomo
fonte