Bagaimana cara mencetak awal file JSON?

1060

Saya memiliki file JSON yang berantakan yang ingin saya cetak sebelumnya - apa cara termudah untuk melakukan ini dengan python? Saya tahu PrettyPrint mengambil "objek", yang saya pikir bisa menjadi file, tapi saya tidak tahu cara mengirim file - hanya menggunakan nama file tidak bekerja.

Gadis
sumber
9
Cobalah untuk menguraikan JSON menggunakan json.loads()dan cukup cetak kamus yang dihasilkan. Atau langsung saja ke bagian Pencetakan cantik dokumentasijson Python untuk .
Blender
1
@Blender jika Anda mengirim jawaban saya akan memberi Anda kredit ... ini mungkin ditutup sebagai duplikat, karena solusinya sama, tetapi pertanyaannya berbeda, jadi mungkin tidak.
Colleen
18
mengapa tidak <your_file.js python -mjson.toolseperti di tautan @ ed?
jfs
11
Saya tidak berpikir itu duplikat karena pencetakan cantik dari baris perintah tidak sama dengan pencetakan cantik secara terprogram dari Python. Voting untuk dibuka kembali.
vitaut

Jawaban:

1664

The jsonmodul sudah mengimplementasikan beberapa pencetakan cukup mendasar dengan indentparameter:

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

Untuk mem-parsing file, gunakan json.load():

with open('filename.txt', 'r') as handle:
    parsed = json.load(handle)
Blender
sumber
143
Untuk pencetakan cantik sederhana ini juga berfungsi tanpa penguraian eksplisit:print json.dumps(your_json_string, indent=4)
Peterino
1
apa yang indent lakukan?
timbram
8
@timbram: Jumlah ruang untuk indentasi.
Blender
9
Tanpa indentasi, Anda hanya mendapatkan satu baris teks jelek, itulah sebabnya saya datang ke sini.
krs013
6
@Peterino Saya harus mengurai string json terlebih dahulu: print(json.dumps(json.loads(your_json_string), indent=2))jika tidak, itu hanya menunjukkan saya sebuah string yang lolos
vladkras
310

Anda dapat melakukan ini di baris perintah:

python3 -m json.tool some.json

(seperti yang telah disebutkan dalam komentar untuk pertanyaan, terima kasih kepada @Kai Petzke untuk saran python3).

Sebenarnya python bukanlah alat favorit saya sejauh json memproses pada baris perintah. Untuk pencetakan yang cukup sederhana tidak masalah, tetapi jika Anda ingin memanipulasi json, ini bisa menjadi rumit. Anda akan segera perlu menulis file skrip terpisah, Anda bisa berakhir dengan peta yang kuncinya adalah "some-key" (python unicode), yang membuat memilih bidang lebih sulit dan tidak benar-benar mengarah ke arah yang cantik -pencetakan.

Anda juga dapat menggunakan jq :

jq . some.json

dan Anda mendapatkan warna sebagai bonus (dan cara perpanjangan lebih mudah).

Tambahan: Ada beberapa kebingungan dalam komentar tentang menggunakan jq untuk memproses file JSON besar di satu sisi, dan memiliki program jq yang sangat besar di sisi lain. Untuk mencetak file yang terdiri dari satu entitas JSON besar, batasan praktisnya adalah RAM. Untuk pencetakan cantik 2GB file yang terdiri dari satu array data dunia nyata, "ukuran set penduduk maksimum" yang diperlukan untuk pencetakan cantik adalah 5GB (apakah menggunakan jq 1.5 atau 1.6). Perhatikan juga bahwa jq dapat digunakan dari dalam python sesudahnya pip install jq.

Gismo Ranas
sumber
4
JQ bagus tetapi ada batas maksimal sehingga tidak berguna untuk file besar. (mis. meledak menangani file 1.15mb
Chris McKee
3
ya, bung, tentu saja, jika Anda menulis filter jq dengan lebih dari 10 ribu baris kode, saya pikir Anda mencoba sesuatu seperti pergi ke mars dengan sepeda.
Gismo Ranas
2
lol: D @ gismo-ranas Versi json.tool disalurkan ke file berfungsi sangat baik pada file besar; dan sangat cepat. Saya suka JQ tetapi memformat apa pun di luar muatan kecil (yang dapat Anda lakukan di sebagian besar editor teks) berada di luar jangkauannya :) Penambahan acak: json-generator.com adalah alat yang rapi untuk membuat data uji
Chris McKee
5
atau hanya:jq '' < some.json
fatal_error
2
Sebenarnya saya sangat menyarankan menggunakan python3 -m json.tool <IN >OUT, karena ini menjaga urutan asli bidang dalam dikts JSON. Penerjemah python versi 2 mengurutkan bidang dalam urutan alfabet, yang sering kali bukan, yang Anda inginkan.
Kai Petzke
55

Anda dapat menggunakan modul pprint built-in (https://docs.python.org/3.6/library/pprint.html) .

Bagaimana Anda dapat membaca file dengan data json dan mencetaknya.

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
sumber
4
Masalah dengan ini adalah bahwa sidik jari akan menggunakan tanda kutip tunggal dan ganda secara bergantian, tetapi json hanya membutuhkan tanda kutip ganda, sehingga json yang dicetak dengan Anda mungkin tidak lagi diurai sebagai json yang valid.
drevicko
1
Ya, tapi itu hanya untuk menghasilkan file json. Tidak mengambil output dan menulisnya lagi dalam file.
ikreb
52

Pygmentize + Python json.tool = Cetak Cantik dengan Sintaks Menyoroti

Menghitung harga adalah alat pembunuh. Lihat ini.

Saya menggabungkan python json.tool dengan pygmentize

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

Lihat tautan di atas untuk menghitung instruksi instalasi.

Demo ini ada pada gambar di bawah ini:

demo

Shubham Chaudhary
sumber
1
Dalam contoh Anda -gsebenarnya tidak berfungsi;) Karena input berasal dari stdin, menghitung tidak dapat membuat perkiraan yang baik. Anda perlu menentukan lexer secara eksplisit:echo '{"foo": "bar"}' | python -m json.tool | pygmentize -l json
Denis The Menace
1
@DenisTheMenace Dulu bekerja pada tahun 2015 ketika saya membuat contoh gambar ini. Sepertinya tidak berfungsi sekarang pada sistem saya juga.
Shubham Chaudhary
36

Gunakan fungsi ini dan jangan berkeringat karena harus mengingat apakah JSON Anda adalah stratau dictlagi - lihat saja hasil cetaknya:

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
sumber
14

Saya pernah menulis prettyjson()fungsi untuk menghasilkan output yang terlihat bagus. Anda dapat mengambil implementasinya dari repo ini .

Fitur utama dari fungsi ini adalah ia mencoba untuk menyimpan dict dan daftar item dalam satu baris sampai maxlinelengthtercapai. Ini menghasilkan lebih sedikit garis JSON, output terlihat lebih kompak dan lebih mudah dibaca.

Anda dapat menghasilkan output semacam ini misalnya:

{
  "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: Saya menempatkan kode ke dalam repo yang terpisah , mengoreksi beberapa bug dan membuat beberapa tweak lainnya.

Andy
sumber
Saya menganggap formatter ini sebagai yang terbaik dari yang disarankan, pantas mendapat lebih banyak upvotes.
thorhunter
13

Agar dapat cukup mencetak dari baris perintah dan dapat memiliki kontrol atas lekukan, dll. Anda dapat mengatur alias yang mirip dengan ini:

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

Dan kemudian gunakan alias dalam salah satu cara ini:

cat myfile.json | jsonpp
jsonpp < myfile.json
Wakil Presiden
sumber
11

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

import pprint
pprint.pprint(json)

print() dibandingkan dengan 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
sumber
pprinttidak menghasilkan dokumen JSON yang valid.
selurvedu
5

Berikut adalah contoh sederhana pencetakan JSON ke konsol dengan cara yang menyenangkan di Python, tanpa mengharuskan JSON berada di komputer Anda sebagai file lokal:

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
sumber
Saya mendapatkan pesan galat berikut dalam Python 3: "TypeError: objek JSON harus str, bukan 'byte'"
Tn. T
3
def saveJson(date,fileToSave):
    with open(fileToSave, 'w+') as fileToSave:
        json.dump(date, fileToSave, ensure_ascii=True, indent=4, sort_keys=True)

Ini berfungsi untuk menampilkan atau menyimpannya ke file.

Pablo Emmanuel De Leo
sumber
1

Saya pikir itu lebih baik untuk mengurai json sebelumnya, untuk menghindari kesalahan:

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
sumber
1

Anda dapat mencoba pprintjson .


Instalasi

$ pip3 install pprintjson

Pemakaian

Cukup cetak JSON dari file menggunakan CLI pprintjson.

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

Cukup cetak JSON dari stdin menggunakan CLI pprintjson.

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

Cukup cetak JSON dari sebuah string menggunakan CLI pprintjson.

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

Cukup cetak JSON dari string dengan indentasi 1.

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

Cukup cetak JSON dari string dan simpan output ke file output.json.

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

Keluaran

masukkan deskripsi gambar di sini

Travis Clarke
sumber
0

Ini jauh dari sempurna, tetapi berhasil.

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

Anda dapat memperbaikinya, menambahkan indentasi dan sebagainya, tetapi jika Anda hanya ingin dapat membaca json yang lebih bersih, inilah cara yang harus dilakukan.

Francisco Perdomo
sumber