Jak wydrukować plik JSON?

1057

Mam plik JSON, który jest bałaganem, który chcę wydrukować - jaki jest najłatwiejszy sposób na zrobienie tego w pythonie? Wiem, że PrettyPrint bierze „obiekt”, który moim zdaniem może być plikiem, ale nie wiem, jak przekazać plik - samo użycie nazwy pliku nie działa.

Colleen
źródło
9
Spróbuj przeanalizować JSON json.loads()i wydrukować wynikowy słownik. Lub po prostu przejdź do sekcji Ładne drukowanie dokumentacjijson Python dla .
Blender
1
@Blender, jeśli opublikujesz odpowiedź, dam ci kredyt ... to może zostać zamknięte jako duplikat, ponieważ rozwiązanie jest takie samo, ale pytanie jest inne, więc może nie.
Colleen,
18
dlaczego nie <your_file.js python -mjson.tooljak w linku @ ed?
jfs
11
Nie wydaje mi się, żeby się powielało, ponieważ ładne drukowanie z wiersza poleceń nie jest tym samym, co ładne drukowanie programowo z Pythona. Głosowanie w celu ponownego otwarcia.
vitaut

Odpowiedzi:

1655

jsonModuł już realizuje podstawowe drukowanie ładna z indentparametrem:

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

Aby przeanalizować plik, użyj json.load():

with open('filename.txt', 'r') as handle:
    parsed = json.load(handle)
Mikser
źródło
142
W przypadku prostego ładnego drukowania działa to również bez wyraźnej analizy:print json.dumps(your_json_string, indent=4)
Peterino
1
co robi tiret?
timbram
8
@timbram: Jest to liczba spacji, według których można wciąć.
Blender
9
Bez wcięcia otrzymujesz tylko jeden wiersz brzydkiego tekstu i dlatego tu przyszedłem.
krs013,
5
@Peterino Najpierw musiałem przeanalizować ciąg Json: w print(json.dumps(json.loads(your_json_string), indent=2))przeciwnym razie pokazał mi tylko ciąg, który uciekł
vladkras
310

Możesz to zrobić w wierszu polecenia:

python3 -m json.tool some.json

(jak już wspomniano w komentarzach do pytania, dzięki @Kai Petzke za sugestię python3).

W rzeczywistości python nie jest moim ulubionym narzędziem, jeśli chodzi o przetwarzanie json w wierszu poleceń. Dla prostego ładnego drukowania jest ok, ale jeśli chcesz manipulować Jsonem, może się to skomplikować. Wkrótce będziesz musiał napisać osobny plik skryptu, możesz skończyć z mapami, których klucze to u „some-key” (unicode python), co utrudnia wybór pól i tak naprawdę nie idzie w kierunku ładnego -druk.

Możesz także użyć jq :

jq . some.json

i dostajesz kolory jako bonus (i znacznie łatwiejsze rozszerzanie).

Dodatek: W komentarzach dotyczących korzystania z jq do przetwarzania dużych plików JSON z jednej strony występuje zamieszanie, a z drugiej strony bardzo duży program jq. Praktycznym ograniczeniem do ładnego drukowania pliku składającego się z jednego dużego obiektu JSON jest pamięć RAM. Aby wydrukować całkiem ładnie plik 2 GB składający się z pojedynczej tablicy danych rzeczywistych, „maksymalny rozmiar rezydentnego zestawu” wymagany do ładnego drukowania wynosił 5 GB (niezależnie od tego, czy używa się jq 1.5, czy 1.6). Zauważ też, że jq może być używane z poziomu Pythona po pip install jq.

Gismo Ranas
źródło
4
JQ jest świetny, ale istnieje maksymalny limit, więc jest bezużyteczny dla dużych plików. (tzn. wysadza się w obsłudze plik 1,15 MB
Chris McKee
3
tak, stary, zdecydowanie, jeśli piszesz filtry jq z ponad 10 000 liniami kodu, myślę, że próbujesz czegoś takiego jak wyprawa na rower.
Gismo Ranas
2
lol: D @ gismo-ranas Wersja json.tool podłączona do pliku działa bardzo dobrze na dużych plikach; i jest głupio szybki. Lubię JQ, ale formatowanie czegokolwiek poza niewielkim ładunkiem (co można zrobić w większości edytorów tekstu) jest poza jego zasięgiem :) Losowe dodawanie: json-generator.com to fajne narzędzie do tworzenia danych testowych
Chris McKee
5
lub po prostu:jq '' < some.json
fatal_error
2
Właściwie zdecydowanie polecam używanie python3 -m json.tool <IN >OUT, ponieważ zachowuje to oryginalną kolejność pól w dyktonach JSON. Wersja 2 interpretera Pythona sortuje pola w porządku rosnącym alfabetycznie, co często nie jest tym, czego chcesz.
Kai Petzke,
55

Możesz użyć wbudowanego modułu pprint (https://docs.python.org/3.6/library/pprint.html) .

Jak można odczytać plik z danymi JSON i wydrukować go.

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
źródło
4
Problem polega na tym, że pprint będzie używał pojedynczych i podwójnych cudzysłowów zamiennie, ale json wymaga tylko podwójnych cudzysłowów, więc twój wydrukowany json może już nie analizować jako prawidłowego json.
drevicko
1
Tak, ale służy tylko do wygenerowania pliku Json. Nie należy pobierać danych wyjściowych i zapisywać ich ponownie w pliku.
ikreb
52

Pygmentize + Python json.tool = Ładny wydruk z podświetlaniem składni

Pygmentize to narzędzie zabójcy. Zobacz.

Łączę python json.tool z pygmentize

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

Zobacz powyższy link, aby uzyskać instrukcję instalacji pygmentize.

Demo tego jest na poniższym obrazku:

próbny

Shubham Chaudhary
źródło
1
W twoim przykładzie -gtak naprawdę nie działa;) Ponieważ dane wejściowe pochodzą ze stdin, pygmentize nie jest w stanie dobrze zgadnąć. Musisz wyraźnie określić leksykon:echo '{"foo": "bar"}' | python -m json.tool | pygmentize -l json
Denis The Menace
1
@DenisTheMenace Kiedyś tworzyłem ten przykładowy obraz. Wygląda na to, że teraz nie działa również w moim systemie.
Shubham Chaudhary
36

Skorzystaj z tej funkcji i nie przejmuj się koniecznością pamiętania, czy Twój JSON to strczy dictjeszcze raz - wystarczy spojrzeć na ładny nadruk:

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
źródło
14

Kiedyś napisałem prettyjson()funkcję do tworzenia ładnie wyglądających wyników. Możesz pobrać implementację z tego repozytorium .

Główną cechą tej funkcji jest to, że próbuje utrzymywać dyktowanie i wyświetlać pozycje w jednym wierszu, dopóki nie maxlinelengthzostanie osiągnięty określony . Powoduje to powstanie mniejszej liczby wierszy JSON, wyjście wygląda na bardziej kompaktowe i łatwiejsze do odczytania.

Możesz wytworzyć tego rodzaju dane wyjściowe na przykład:

{
  "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 Dec'19: Umieściłem kod w osobnym repozytorium , poprawiłem kilka błędów i wprowadziłem kilka innych poprawek.

Andy
źródło
Uważam, że ten formatyzator jest najlepszy z sugerowanych, zasługuje na więcej głosów pozytywnych.
Thorhunter
13

Aby móc ładnie drukować z wiersza poleceń i mieć kontrolę nad wcięciami itp., Możesz ustawić alias podobny do tego:

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

A następnie użyj aliasu na jeden z następujących sposobów:

cat myfile.json | jsonpp
jsonpp < myfile.json
VP
źródło
11

Użyj pprint: https://docs.python.org/3.6/library/pprint.html

import pprint
pprint.pprint(json)

print() w porównaniu do 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
źródło
pprintnie tworzy ważnego dokumentu JSON.
selurvedu
5

Oto prosty przykład ładnego drukowania JSON na konsoli w przyjemny sposób w Pythonie, bez wymagania, aby JSON był na twoim komputerze jako plik lokalny:

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
źródło
W Pythonie 3 pojawia się następujący komunikat o błędzie: „Błąd typu: obiekt JSON musi być ciągiem, a nie„ bajtami ””
Pan T
3
def saveJson(date,fileToSave):
    with open(fileToSave, 'w+') as fileToSave:
        json.dump(date, fileToSave, ensure_ascii=True, indent=4, sort_keys=True)

Działa, aby wyświetlić lub zapisać go w pliku.

Pablo Emmanuel De Leo
źródło
1

Myślę, że lepiej jest wcześniej przeanalizować plik Json, aby uniknąć błędów:

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
źródło
1

Możesz spróbować pprintjson .


Instalacja

$ pip3 install pprintjson

Stosowanie

Ładnie wydrukuj JSON z pliku za pomocą CLI pprintjson.

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

Ładny wydruk JSON ze standardowego interfejsu przy użyciu CLI pprintjson.

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

Całkiem drukuj JSON z łańcucha za pomocą CLI pprintjson.

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

Ładny nadruk JSON z sznurka z wcięciem 1.

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

Ładnie wydrukuj JSON z łańcucha i zapisz dane wyjściowe w pliku output.json.

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

Wynik

wprowadź opis zdjęcia tutaj

Travis Clarke
źródło
0

Jest daleki od ideału, ale spełnia swoje zadanie.

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

możesz to poprawić, dodać wcięcia i tak dalej, ale jeśli chcesz po prostu czytać czystsze JSON, to jest to właściwa droga.

Francisco Perdomo
źródło