Как распечатать файл JSON?

1061

У меня есть JSON-файл, который я хочу распечатать - это беспорядок, какой самый простой способ сделать это в python? Я знаю, что PrettyPrint принимает «объект», который, я думаю, может быть файлом, но я не знаю, как передать файл - просто использование имени файла не работает.

Коллин
источник
9
Попробуйте разобрать JSON, используя json.loads()и распечатать полученный словарь. Или просто перейдите к разделу печати Pretty для документации поjson Python .
Блендер
1
@ Blender, если вы отправите ответ, я вам скажу ... это может быть закрыто как дубликат, потому что решение такое же, но вопрос другой, так что, возможно, нет.
Коллин
18
почему не <your_file.js python -mjson.toolкак в ссылке @ ed?
JFS
11
Я не думаю, что это дубликат, потому что симпатичная печать из командной строки - это не то же самое, что симпатичная печать программно из Python. Голосование возобновить.
Витаут

Ответы:

1665

В 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)
смеситель
источник
143
Для простой симпатичной печати это также работает без явного разбора:print json.dumps(your_json_string, indent=4)
Peterino
1
что делает отступ?
Тимбрам
8
@timbram: это количество пробелов для отступа.
Блендер
9
Без отступа вы получите только одну строку уродливого текста, поэтому я и пришел сюда.
krs013
6
@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, это может стать слишком сложным. Вскоре вам понадобится написать отдельный скрипт-файл, вы можете получить карты, ключи которых у вас "some-key" (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,15 Мб) github.com/stedolan/jq/issues/1041
Крис Макки,
3
да, мужик, определенно, если вы пишете jq-фильтры с более чем 10K строками кода, я думаю, вы пытаетесь что-то наподобие поездки на Марс с велосипедом.
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)
ikreb
источник
4
Проблема в том, что pprint будет использовать одинарные и двойные кавычки взаимозаменяемо, но json требует только двойные кавычки, поэтому ваш напечатанный json больше не может анализироваться как действительный json.
drevicko
1
Да, но это только для вывода файла JSON. Не брать вывод и снова записывать его в файл.
Икреб
52

Pygmentize + Python json.tool = Красивая печать с подсветкой синтаксиса

Пигментирование является убийственным инструментом. Посмотри это.

Я объединяю python json.tool с пигментированием

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

Смотрите ссылку выше для пигментирования инструкции по установке.

Демонстрация этого на изображении ниже:

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

Шубхам Чаудхари
источник
1
В вашем примере на -gсамом деле не работает;) Поскольку входные данные поступают из стандартного ввода, pygmentize не может сделать правильное предположение. Вам нужно явно указать лексер:echo '{"foo": "bar"}' | python -m json.tool | pygmentize -l json
Denis The Menace
1
@DenisTheMenace Он работал в 2015 году, когда я создал этот пример изображения. Похоже, теперь он не работает на моей системе.
Шубхам Чаудхари
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)
zelusp
источник
15

Однажды я написал 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: я поместил код в отдельный репозиторий , исправил несколько ошибок и внес несколько других изменений.

Энди
источник
Я считаю этот форматтер лучшим из предложенных, заслуживает большего количества голосов.
Охотник
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)
p3quod
источник
1

Вы можете попробовать pprintjson .


Установка

$ pip3 install pprintjson

Применение

Довольно распечатать JSON из файла, используя pprintjson CLI.

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

Довольно распечатать JSON из стандартного ввода, используя интерфейс командной строки pprintjson.

$ 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

Вывод

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

Трэвис Кларк
источник
-1

Это далеко от совершенства, но это делает работу.

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

Вы можете улучшить его, добавить отступы и т. д., но если вы просто хотите читать чище json, это путь.

Франциско Пердомо
источник