จะพิมพ์ไฟล์ JSON ได้อย่างไร


1059

ฉันมีไฟล์ JSON ที่ยุ่งเหยิงที่ฉันต้องการที่จะพิมพ์สวย - วิธีที่ง่ายที่สุดในการทำเช่นนี้กับงูหลามคืออะไร? ฉันรู้ว่า PrettyPrint ใช้ "วัตถุ" ซึ่งฉันคิดว่าสามารถเป็นไฟล์ได้ แต่ฉันไม่รู้วิธีส่งไฟล์ด้วย - แค่ใช้ชื่อไฟล์ไม่ทำงาน


9
ลองแยกวิเคราะห์ JSON โดยใช้json.loads()และพิมพ์พจนานุกรมที่น่าสนใจ หรือเพียงแค่ข้ามกับพริตตี้พิมพ์ส่วนหนึ่งของงูหลามเอกสาร json
เครื่องปั่น


1
@ ผู้ยืมถ้าคุณโพสต์คำตอบฉันจะให้เครดิตคุณ ... นี่อาจจะเป็นการปิดซ้ำซ้อนเพราะวิธีการแก้ปัญหาเหมือนกัน แต่คำถามนั้นแตกต่างกันดังนั้นอาจไม่ใช่
คอลลีน

18
ทำไมไม่<your_file.js python -mjson.toolเป็นเช่นในลิงค์ของ @ ed?
jfs

11
ฉันไม่คิดว่ามันจะซ้ำกันเพราะการพิมพ์แบบสวย ๆ จากบรรทัดคำสั่งไม่เหมือนกับการพิมพ์แบบสวย ๆ โดยทางโปรแกรมจาก Python การลงคะแนนเพื่อเปิดใหม่
vitaut

คำตอบ:


1658

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
เยื้องทำอะไร
timbram

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)

หลามจริง ๆ แล้วไม่ใช่เครื่องมือที่ฉันโปรดปรานเท่าที่การประมวลผล json ในบรรทัดคำสั่งเกี่ยวข้อง สำหรับการพิมพ์แบบง่าย ๆ ก็โอเค แต่ถ้าคุณต้องการจัดการกับ json มันอาจกลายเป็นเรื่องที่ซับซ้อน ในไม่ช้าคุณจะต้องเขียนไฟล์สคริปต์แยกต่างหากคุณสามารถจบลงด้วยแผนที่ซึ่งมีกุญแจคือ u "some-key" (python unicode) ซึ่งทำให้การเลือกฟิลด์ยากขึ้นและไม่ได้ไปในทิศทางที่สวย -printing

คุณยังสามารถใช้ jq :

jq . some.json

และคุณจะได้รับสีเป็นโบนัส (และความสามารถในการขยายได้ง่ายขึ้น)

ภาคผนวก: มีความสับสนในความคิดเห็นเกี่ยวกับการใช้ jq เพื่อประมวลผลไฟล์ JSON ขนาดใหญ่ในด้านหนึ่งและมีโปรแกรม jq ขนาดใหญ่มากในอีกด้านหนึ่ง สำหรับการพิมพ์ไฟล์ที่สวยงามซึ่งประกอบด้วยเอนทิตี JSON ขนาดใหญ่ข้อ จำกัด ที่ใช้ได้คือ RAM สำหรับการพิมพ์ไฟล์ 2GB ที่สวยงามซึ่งประกอบด้วยข้อมูลในโลกแห่งความจริงเดียว "ขนาดชุดที่อยู่อาศัยสูงสุด" ที่จำเป็นสำหรับการพิมพ์แบบสวยคือ 5GB (ไม่ว่าจะใช้ jq 1.5 หรือ 1.6) โปรดทราบว่า jq สามารถใช้งานได้จากภายใน python หลังจากpip install jqนั้น


4
JQ ยอดเยี่ยม แต่มีขีด จำกัด สูงสุดดังนั้นมันจึงไม่มีประโยชน์สำหรับไฟล์ขนาดใหญ่ (เช่นเพิ่มการจัดการไฟล์ 1.15mb) github.com/stedolan/jq/issues/1041
Chris McKee

3
ใช่ผู้ชายแน่นอนถ้าคุณกำลังเขียนตัวกรอง jq ที่มีมากกว่า 10K บรรทัดของรหัสฉันคิดว่าคุณกำลังพยายามทำอะไรบางอย่างเช่นจะไปดาวอังคารด้วยจักรยาน
Gismo Ranas

2
lol: D @ gismo-ranas เวอร์ชัน json.tool ไปยังไฟล์ทำงานได้ดีจริง ๆ กับไฟล์ขนาดใหญ่ และรวดเร็วอย่างโง่เขลา ฉันชอบ JQ แต่การจัดรูปแบบอะไรก็ตามที่มีขนาดเล็ก (ซึ่งคุณสามารถทำได้ในโปรแกรมแก้ไขข้อความส่วนใหญ่) อยู่ไกลเกินเอื้อม :) การเพิ่มแบบสุ่ม: json-generator.comเป็นเครื่องมือที่เรียบร้อยในการทำข้อมูลทดสอบ
Chris McKee

5
หรือเพียงแค่:jq '' < some.json
fatal_error

2
ที่จริงฉันขอแนะนำอย่างยิ่งให้ใช้python3 -m json.tool <IN >OUTเนื่องจากจะรักษาลำดับเดิมของฟิลด์ใน JSON dicts python interpreter รุ่นที่ 2 เรียงลำดับฟิลด์ตามลำดับตัวอักษรซึ่งมักจะไม่ใช่สิ่งที่คุณต้องการ
Kai Petzke

55

คุณสามารถใช้โมดูลโมดูลในตัว (https://docs.python.org/3.6/library/pprint.html)(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 ต้องการเครื่องหมายคำพูดคู่เท่านั้นดังนั้น json ที่พิมพ์ของคุณอาจไม่แยกวิเคราะห์เป็น json ที่ถูกต้องอีกต่อไป
drevicko

1
ใช่ แต่เป็นเพียงการส่งออกไฟล์ json ที่จะไม่เอาออกและเขียนมันอีกครั้งในไฟล์
ikreb

52

Pyounceize + Python json.tool = พิมพ์สวยด้วยการเน้นไวยากรณ์

การลงโทษเป็นเครื่องมือนักฆ่า ดูนี่.

ฉันรวมไพ ธ อน json.tool กับการเพิ่มจำนวน

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

ดูลิงค์ด้านบนสำหรับคำแนะนำในการติดตั้งแบบเหมาจ่าย

ตัวอย่างนี้อยู่ในภาพด้านล่าง:

การสาธิต


1
ในตัวอย่างของคุณใช้งาน-gไม่ได้;) เนื่องจากอินพุตมาจาก stdin การเพิ่มจำนวนจึงไม่สามารถเดาได้ดี คุณต้องระบุ lexer อย่างชัดเจน:echo '{"foo": "bar"}' | python -m json.tool | pygmentize -l json
Denis The Menace

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()ฟังก์ชั่นเพื่อสร้างผลลัพธ์ที่ดูดี คุณสามารถคว้าการใช้งานจากrepo นี้นี้

คุณสมบัติหลักของฟังก์ชั่นนี้คือมันพยายามที่จะเก็บ dict และรายการในหนึ่งบรรทัดจนกว่าจะมีบางอย่าง 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: ฉันวางโค้ดลงในrepo ที่แยกต่างหากแก้ไขข้อผิดพลาดเล็กน้อยและทำการปรับแต่งอื่น ๆ


ฉันคิดว่าฟอร์แมตเตอร์นี้ดีที่สุดจากสิ่งที่แนะนำควรได้รับการโหวตมากขึ้น
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 ไม่ใช่" bytes ""
Mr. 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 จากไฟล์โดยใช้ pprintjson CLI

$ 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 ที่สะอาดกว่านี้เป็นวิธีที่จะไป

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.