Як красиво надрукувати файл JSON?


1057

У мене є файл JSON - це безлад, який я хочу досить віддрукувати - який найпростіший спосіб зробити це в python? Я знаю, що PrettyPrint приймає "об'єкт", який, на мою думку, може бути файлом, але я не знаю, як передавати файл - просто використання назви файлу не працює.


9
Спробуйте розібрати JSON, використовуючи json.loads()і досить друкувати цей словник. Або просто перейти до розділу Досить друку документаціїjson Python для .
Блендер


1
@ Blender, якщо ви опублікуєте відповідь, я дам вам кредит ... це може бути закрито як дублікат, тому що рішення те саме, але питання інше, тому, можливо, ні.
Коллін

18
чому б не так, <your_file.js python -mjson.toolяк у посиланні @ ed?
jfs

11
Я не думаю, що це дублікат, тому що симпатична друк з командного рядка не є такою ж, як симпатична друк програмно з Python. Голосування за повторне відкриття.
vitaut

Відповіді:


1655

jsonМодуль вже реалізує деяку базову симпатичну друк з indentпараметром:

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

Щоб розібрати файл, використовуйте json.load():

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

142
Для простої симпатичної друку це також працює без явного розбору:print json.dumps(your_json_string, indent=4)
Peterino

1
що робить відступ?
тембрам

8
@timbram: це кількість пробілів для відступу.
Блендер

9
Без відступу ви просто отримуєте один рядок потворного тексту, саме тому я прийшов сюди.
krs013

5
@Peterino Спочатку я повинен був розібрати рядок json: print(json.dumps(json.loads(your_json_string), indent=2))інакше це просто показало мені рятується рядок
vladkras

310

Це можна зробити в командному рядку:

python3 -m json.tool some.json

(як уже згадувалося в коментарях до питання, завдяки @Kai Petzke за пропозицію python3).

Насправді python не є моїм улюбленим інструментом, що стосується обробки json у командному рядку. Для простого симпатичного друку це нормально, але якщо ви хочете маніпулювати json, він може ускладнитися. Незабаром вам потрібно буде написати окремий файл-скрипт, ви можете закінчитись картами, чиї ключі є "якимось ключем" (python unicode), що ускладнює вибір полів і насправді не йде в напрямку досить -друкування.

Ви також можете використовувати jq :

jq . some.json

і ви отримуєте кольори як бонус (і це полегшує розширення).

Додаток: У коментарях є деяка плутанина щодо використання jq для обробки великих файлів JSON, з одного боку, та наявності дуже великої програми jq, з іншого. Для гарного друку файлу, що складається з одного великого об'єкта JSON, практичне обмеження - оперативна пам'ять. Для гарного друку файлу 2 Гб, що складається з одного масиву даних у реальному світі, "максимальний розмір резидентного набору", необхідний для гарної друку, становив 5 ГБ (незалежно від використання jq 1.5 або 1.6). Зауважте також, що jq можна використовувати зсередини python після pip install jq.


4
JQ чудовий, але існує максимальний ліміт, тому його марно використовувати для великих файлів. (Тобто підриває обробку файлу 1.15MB) github.com/stedolan/jq/issues/1041
Кріс Маккі

3
так, чоловіче, безумовно, якщо ти пишеш фільтри jq з кодом понад 10 К, я думаю, ти намагаєшся щось схоже їхати в марс на велосипеді.
Gismo Ranas

2
lol: D @ gismo-ranas Версія json.tool, перекладена у файл, дуже добре працює на великих файлах; і тупо швидко. Мені подобається JQ, але форматування всього, що перевищує невелику корисну навантаження (що ви могли б зробити в більшості текстових редакторів), є поза його досяжністю :) Випадкове додавання: json-generator.com - це акуратний інструмент для тестових даних
Кріс Маккі

5
або просто:jq '' < some.json
fatal_error

2
Насправді я настійно рекомендую використовувати python3 -m json.tool <IN >OUT, оскільки це зберігає початковий порядок полів у диктатах JSON. Інтерпретатор python версії 2 сортує поля в алфавітному порядку зростання, що часто не є тим, що ви хочете.
Кай Петцке

55

Ви можете використовувати вбудований модуль pprint (https://docs.python.org/3.6/library/pprint.html) .

Як ви можете прочитати файл із даними json та роздрукувати його.

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
Проблема з цим полягає в тому, що pprint буде використовувати єдині та подвійні лапки безперервно, але json вимагає лише подвійних лапок, тож ваш pprinted json може більше не розбиратись як дійсний json.
drevicko

1
Так, але це лише для виведення файлу json. Не брати вихід і записати його знову у файл.
ikreb

52

Pygmentize + Python json.tool = Гарне друк із підсвічуванням синтаксису

Пігментізація - це вбивчий інструмент. Дивіться це.

Я поєдную python json.tool з pygmentize

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

Перегляньте посилання вище для інструкції з установки пігментізу.

Демонстрація цього опису на зображенні нижче:

демонстрація


1
У вашому прикладі -gнасправді не працює;) Оскільки введення надходить від stdin, пігментізація не в змозі добре здогадатися. Потрібно чітко вказати лексеру:echo '{"foo": "bar"}' | python -m json.tool | pygmentize -l json
Денис Грозний

1
@DenisTheMenace Він працював у 2015 році, коли я створив це прикладне зображення. Схоже, зараз це не працює і в моїй системі.
Shubham Chaudhary

36

Використовуйте цю функцію і не спітніть, не пам'ятаючи, чи є ваш JSON знову strчи dictзнову - просто подивіться на симпатичний принт:

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

Колись я написав prettyjson()функцію для отримання гарного вигляду. Ви можете захопити реалізацію з цього репо .

Основна особливість цієї функції полягає в тому, що вона намагається зберігати елементи диктування та списку в одному рядку, поки не maxlinelengthбуде досягнуто певного . Це створює менше рядків JSON, вихід виглядає компактніше і легше читати.

Наприклад, ви можете отримати такий вид випуску:

{
  "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: Я помістив код в окремий репо , виправив кілька помилок і зробив декілька інших перетворень.


Я вважаю, що цей формат є найкращим із запропонованих, заслуговує на більшу кількість результатів.
thorhunter

13

Щоб мати можливість друкувати з командного рядка та мати контроль над відступом тощо, ви можете встановити псевдонім, подібний до цього:

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

А потім використовувати псевдонім одним із таких способів:

cat myfile.json | jsonpp
jsonpp < myfile.json

11

Використовуйте pprint: https://docs.python.org/3.6/library/pprint.html

import pprint
pprint.pprint(json)

print() у порівнянні з 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'}

pprintне створює дійсного документа JSON.
selurvedu

5

Ось простий приклад гарного друку JSON на консолі приємним способом на Python, не вимагаючи, щоб JSON знаходився на вашому комп’ютері як локальний файл:

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

Я отримую таке повідомлення про помилку в Python 3: "TypeError: об'єкт JSON повинен бути str, а не" байтами ".
Містер T

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

Він працює для відображення або збереження його у файл.


1

Я думаю, що краще проаналізувати json раніше, щоб уникнути помилок:

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

Ви можете спробувати pprintjson .


Установка

$ pip3 install pprintjson

Використання

Гарне друк JSON з файлу за допомогою CLpr pprintjson.

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

Симпатичний друк JSON від stdin за допомогою pprintjson CLI.

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

Симпатичний друк JSON з рядка за допомогою pprintjson CLI.

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

Гарненький друк JSON з рядка з відступом 1.

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

Гарненько надрукуйте JSON з рядка та збережіть вихід у файл output.json.

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

Вихідні дані

введіть тут опис зображення


0

Це далеко не ідеально, але це робить свою роботу.

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

ви можете покращити його, додати відступи тощо, але якщо ви просто хочете мати можливість прочитати чистіший json, це шлях.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.