Làm thế nào để in đẹp một tệp JSON?


1059

Tôi có một tệp JSON là một mớ hỗn độn mà tôi muốn in đẹp-- cách dễ nhất để làm điều này trong python là gì? Tôi biết PrettyPrint lấy một "đối tượng", mà tôi nghĩ có thể là một tệp, nhưng tôi không biết làm thế nào để truyền tệp vào - chỉ sử dụng tên tệp không hoạt động.


9
Cố gắng phân tích JSON bằng cách sử dụng json.loads()và in đẹp từ điển đó. Hoặc chỉ cần bỏ qua phần In đẹp của tài liệujson Python cho .
Máy xay sinh tố


1
@Blender nếu bạn đăng câu trả lời tôi sẽ cung cấp cho bạn tín dụng ... điều này có thể bị đóng như một bản sao, vì giải pháp là như nhau, nhưng câu hỏi thì khác, nên có lẽ là không.
Colleen

18
Tại sao không <your_file.js python -mjson.toolnhư trong liên kết của @ ed?
JFS

11
Tôi không nghĩ nó trùng lặp vì in đẹp từ dòng lệnh không giống như in đẹp theo chương trình từ Python. Bỏ phiếu để mở lại.
vitaut

Câu trả lời:


1661

Các jsonmô-đun đã thực hiện một số in ấn cơ bản với indenttham số:

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

Để phân tích một tệp, sử dụng json.load():

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

143
Để in đơn giản, thao tác này cũng hoạt động mà không cần phân tích cú pháp rõ ràng:print json.dumps(your_json_string, indent=4)
Peterino

1
thụt lề làm gì?
timbram

8
@timbram: Đó là số lượng không gian để thụt lề.
Máy xay sinh tố

9
Không có thụt lề, bạn chỉ nhận được một dòng văn bản xấu xí, đó là lý do tại sao tôi đến đây.
krs013

6
@Peterino Tôi phải phân tích chuỗi json trước: print(json.dumps(json.loads(your_json_string), indent=2))nếu không, nó chỉ cho tôi một chuỗi thoát
vladkras

310

Bạn có thể làm điều này trên dòng lệnh:

python3 -m json.tool some.json

(như đã đề cập trong phần bình luận cho câu hỏi, cảm ơn @Kai Petzke về đề xuất python3).

Trên thực tế python không phải là công cụ yêu thích của tôi khi có liên quan đến xử lý json trên dòng lệnh. Đối với in đơn giản đẹp là ok, nhưng nếu bạn muốn thao tác json, nó có thể trở nên quá phức tạp. Bạn sẽ sớm cần phải viết một tệp tập lệnh riêng biệt, bạn có thể kết thúc bằng các bản đồ có các khóa là u "some-key" (python unicode), khiến việc chọn các trường khó khăn hơn và không thực sự đi theo hướng đẹp in dấu.

Bạn cũng có thể sử dụng jq :

jq . some.json

và bạn có được màu sắc như một phần thưởng (và cách dễ dàng mở rộng hơn).

Phụ lục: Có một số nhầm lẫn trong các nhận xét về việc sử dụng jq để xử lý các tệp JSON lớn một mặt và mặt khác có chương trình jq rất lớn. Để in đẹp một tệp bao gồm một thực thể JSON lớn duy nhất, giới hạn thực tế là RAM. Để in đẹp một tệp 2 GB bao gồm một mảng dữ liệu trong thế giới thực, "kích thước bộ cư trú tối đa" cần thiết cho in đẹp là 5 GB (cho dù sử dụng jq 1.5 hay 1.6). Cũng lưu ý rằng jq có thể được sử dụng từ bên trong python sau pip install jq.


4
JQ là tuyệt vời nhưng có một giới hạn tối đa vì vậy nó vô dụng đối với các tệp lớn. (tức là thổi lên xử lý tệp 1,15mb) github.com/stedolan/jq/issues/1041
Chris McKee

3
vâng, chắc chắn, nếu bạn đang viết bộ lọc jq với hơn 10K dòng mã, tôi nghĩ bạn đang thử một cái gì đó như đi đến sao hỏa bằng xe đạp.
Gismo Ranas

2
lol: D @ gismo-ranas Phiên bản json.tool được chuyển đến một tệp hoạt động thực sự tốt trên các tệp lớn; và là ngu ngốc nhanh chóng. Tôi thích JQ nhưng định dạng bất cứ thứ gì ngoài một tải trọng nhỏ (mà bạn có thể làm trong hầu hết các trình soạn thảo văn bản) nằm ngoài khả năng của nó :) Ngoài ra ngẫu nhiên: json-generator.com là một công cụ gọn gàng để tạo dữ liệu thử nghiệm
Chris McKee

5
hoặc chỉ:jq '' < some.json
fatal_error 9/12/2016

2
Trên thực tế tôi thực sự khuyên bạn nên sử dụng python3 -m json.tool <IN >OUT, vì điều này sẽ giữ thứ tự ban đầu của các trường trong các ký tự JSON. Trình thông dịch python phiên bản 2 sắp xếp các trường theo thứ tự tăng dần theo thứ tự bảng chữ cái, thường không phải là những gì bạn muốn.
Kai Petzke

55

Bạn có thể sử dụng bản in modul tích hợp (https://docs.python.org/3.6/l Library / pprint.html) .

Làm thế nào bạn có thể đọc các tập tin với dữ liệu json và in nó ra.

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
Vấn đề với điều này là pprint sẽ sử dụng dấu ngoặc đơn và dấu ngoặc kép thay thế cho nhau, nhưng json chỉ yêu cầu dấu ngoặc kép, vì vậy json có dấu của bạn có thể không còn phân tích thành json hợp lệ.
drevicko

1
Có, nhưng nó chỉ xuất ra một tệp json. Không lấy đầu ra và viết lại trong một tập tin.
ikreb

52

Pyributionize + Python json.tool = In đẹp với tô sáng cú pháp

Pyributionize là một công cụ giết người. Xem cái này

Tôi kết hợp python json.tool với pyributionize

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

Xem liên kết ở trên để biết hướng dẫn cài đặt pyributionize.

Một bản demo của điều này là trong hình dưới đây:

bản giới thiệu


1
Trong ví dụ của bạn -gkhông thực sự hoạt động;) Vì đầu vào đến từ stdin, pyributionize không thể đưa ra dự đoán tốt. Bạn cần xác định rõ ràng từ vựng:echo '{"foo": "bar"}' | python -m json.tool | pygmentize -l json
Denis The Menace

1
@DenisTheMenace Nó được sử dụng để làm việc vào năm 2015 khi tôi tạo hình ảnh ví dụ này. Nó dường như không hoạt động trên hệ thống của tôi.
Shubham Chaudhary

36

Sử dụng chức năng này và không cần phải nhớ rằng JSON của bạn là một strhay dictmột lần nữa - chỉ cần nhìn vào bản in đẹp:

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

Tôi đã từng viết một prettyjson()chức năng để tạo ra đầu ra đẹp mắt. Bạn có thể lấy việc thực hiện từ repo này .

Tính năng chính của chức năng này là nó cố gắng giữ dict và liệt kê các mục trong một dòng cho đến khi maxlinelengthđạt được một số nhất định . Điều này tạo ra ít dòng JSON hơn, đầu ra trông gọn hơn và dễ đọc hơn.

Bạn có thể sản xuất loại đầu ra này chẳng hạn:

{
  "grid": {"port": "COM5"},
  "policy": {
    "movingaverage": 5,
    "hysteresis": 5,
    "fan1": {
      "name": "CPU",
      "signal": "cpu",
      "mode": "auto",
      "speed": 100,
      "curve": [[0, 75], [50, 75], [75, 100]]
    }
}

CẬP NHẬT 19 tháng 12: Tôi đã đặt mã vào một repo riêng , sửa một vài lỗi và thực hiện một vài điều chỉnh khác.


Tôi coi định dạng này là tốt nhất từ ​​những người được đề xuất, xứng đáng nhận được nhiều sự ủng hộ hơn.
thorhunter

13

Để có thể in đẹp từ dòng lệnh và có thể kiểm soát thụt lề, v.v. bạn có thể thiết lập một bí danh tương tự như sau:

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

Và sau đó sử dụng bí danh theo một trong những cách sau:

cat myfile.json | jsonpp
jsonpp < myfile.json

11

Sử dụng pprint: https://docs.python.org/3.6/l Library / pprint.html

import pprint
pprint.pprint(json)

print() so với 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'}

pprintkhông tạo ra một tài liệu JSON hợp lệ.
selurvedu

5

Đây là một ví dụ đơn giản về việc in JSON đẹp lên bàn điều khiển theo cách hay trong Python, mà không yêu cầu JSON phải có trên máy tính của bạn dưới dạng tệp cục bộ:

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

Tôi nhận được thông báo lỗi sau trong Python 3: "TypeError: đối tượng JSON phải là str, không phải 'byte'"
Ông T

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

Nó hoạt động để hiển thị hoặc lưu nó vào một tập tin.


1

Tôi nghĩ rằng tốt hơn là phân tích json trước, để tránh lỗi:

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

Bạn có thể thử pprintjson .


Cài đặt

$ pip3 install pprintjson

Sử dụng

Khá in JSON từ một tệp bằng cách sử dụng pprintjson CLI.

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

JSON in đẹp từ một stdin bằng pprintjson CLI.

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

JSON đẹp in từ một chuỗi bằng pprintjson CLI.

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

JSON đẹp in từ một chuỗi có thụt lề 1.

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

Khá in JSON từ một chuỗi và lưu đầu ra vào tệp output.json.

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

Đầu ra

nhập mô tả hình ảnh ở đây


0

Nó không hoàn hảo, nhưng nó thực hiện công việc.

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

bạn có thể cải thiện nó, thêm thụt lề và vân vân, nhưng nếu bạn chỉ muốn có thể đọc một json sạch hơn, đây là cách để đi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.