ToolDeck

JSON Formatter Python — คู่มือ json.dumps()

·Backend Developer·ตรวจสอบโดยDmitri Volkov·เผยแพร่เมื่อ

ใช้ จัดรูปแบบและตกแต่ง JSON ฟรีโดยตรงในเบราว์เซอร์ของคุณ — ไม่ต้องติดตั้ง

ลอง จัดรูปแบบและตกแต่ง JSON ออนไลน์ →

เมื่อฉันกำลัง debug Python API client สิ่งแรกที่ฉันนึกถึงคือ python pretty print json — เพียงหนึ่งครั้งที่เรียก json.dumps(data, indent=4) ก็เปลี่ยน blob ที่อ่านไม่ออกเป็น string ที่นำทางได้ทันที module json ที่มีในตัวของ Python จัดการเรื่องนี้ทั้งหมดใน standard library — ไม่ต้องติดตั้ง third-party ถ้าต้องการผลลัพธ์รวดเร็วโดยไม่ต้องเขียนโค้ด JSON Formatter ของ ToolDeck ทำได้ทันที คู่มือนี้ครอบคลุมทุกวิธีในทางปฏิบัติ: json.dumps() พร้อมพารามิเตอร์ทั้งหมด, pprint, orjson สำหรับการจัดรูปแบบที่มีประสิทธิภาพสูง, CLI json.tool, และสถานการณ์จริงเช่นการจัดรูปแบบ API response และการอ่านจากดิสก์ — ทั้งหมดด้วย code ที่รองรับ Python 3.8+ รวมถึงการ serialize ประเภทกำหนดเองเช่น datetime และ UUID, การ stream ไฟล์ขนาด gigabyte ด้วย ijson, และการไฮไลต์ syntax บน terminal ด้วย rich.

สรุปสำคัญ
  • json.dumps(data, indent=4) มีใน stdlib ของ Python ตั้งแต่เวอร์ชัน 2.6 — ไม่ต้องติดตั้ง
  • ส่งผ่าน ensure_ascii=False ทุกครั้งที่ข้อมูลมีตัวอักษรที่มีสำเนียง อักขระ CJK หรือ emoji
  • สำหรับ datetime, UUID หรือ class กำหนดเอง ใช้พารามิเตอร์ default= หรือสืบทอด json.JSONEncoder
  • separators=(',', ':') ลบช่องว่างทั้งหมด — ใช้สำหรับส่งข้อมูลผ่านเครือข่ายหรือฝังใน URL
  • orjson เร็วกว่า stdlib 5–10× และรองรับ datetime และ uuid.UUID แบบ native
  • pprint.pprint() ส่งออก Python syntax (True/None) ไม่ใช่ JSON ที่ถูกต้อง — ไม่ควรใช้สำหรับไฟล์หรือ API response
  • สำหรับไฟล์ JSON ที่ใหญ่กว่า 50 MB ให้ stream ด้วย ijson แทน json.load() เพื่อหลีกเลี่ยง MemoryError

JSON Pretty Printing คืออะไร?

Pretty printing แปลง JSON string ที่แน่นและย่อขนาดให้เป็นรูปแบบที่อ่านง่าย ด้วยการย่อหน้าและขึ้นบรรทัดใหม่ที่สม่ำเสมอ การแปลงนี้เป็นเพียงการแสดงผล: ข้อมูลเหมือนกันทุกอย่าง มีเพียงการนำเสนอที่เปลี่ยนไป module json ของ Python จัดการเรื่องนี้ทั้งหมดใน standard library — ไม่ต้องติดตั้งเพิ่ม

Before · json
After · json
{"id":"usr_9f3a2b","name":"สมชาย ใจดี","roles":["admin","editor"],"prefs":{"theme":"dark","lang":"th"}}
{
    "id": "usr_9f3a2b",
    "name": "สมชาย ใจดี",
    "roles": [
        "admin",
        "editor"
    ],
    "prefs": {
        "theme": "dark",
        "lang": "th"
    }
}

json.dumps() — วิธีมาตรฐานในการจัดรูปแบบ JSON

json.dumps() เป็นส่วนหนึ่งของ standard library ของ Python ตั้งแต่ Python 2.6 — เพียง import json, ไม่ต้องติดตั้งเพิ่ม มัน serialize Python object ที่รองรับ JSON เป็น string ที่จัดรูปแบบแล้ว พารามิเตอร์หลักคือ indent: ตั้งค่าเป็น 4 (หรือ 2) เพื่อให้อ่านง่าย

Python 3.8+ — ตัวอย่างขั้นต่ำ
import json

phuchai = {
    "id": "usr_9f3a2b",
    "name": "สมชาย ใจดี",
    "roles": ["admin", "editor"],
    "prefs": {"theme": "dark", "lang": "th"}
}

print(json.dumps(phuchai, indent=4, ensure_ascii=False))
# ผลลัพธ์:
# {
#     "id": "usr_9f3a2b",
#     "name": "สมชาย ใจดี",
#     "roles": [
#         "admin",
#         "editor"
#     ],
#     "prefs": {
#         "theme": "dark",
#         "lang": "th"
#     }
# }

สำหรับการใช้งาน production มักต้องการ sort_keys=True (ผลลัพธ์สม่ำเสมอข้ามการรัน) และ ensure_ascii=False (เก็บอักขระภาษาไทย):

Python 3.8+ — พร้อม sort_keys และ ensure_ascii
import json

api_response = {
    "timestamp": "2024-05-01T10:30:00Z",
    "status": "success",
    "data": {
        "user_id": "usr_9f3a2b",
        "display_name": "สุดา มีสุข",
        "city": "กรุงเทพ",
        "score": 4892.5,
        "tags": ["python", "backend", "api"]
    }
}

print(json.dumps(api_response, indent=4, sort_keys=True, ensure_ascii=False))
# ผลลัพธ์ (คีย์เรียงแล้ว เก็บภาษาไทย):
# {
#     "data": {
#         "city": "กรุงเทพ",
#         "display_name": "สุดา มีสุข",
#         "score": 4892.5,
#         "tags": ["api", "backend", "python"],
#         "user_id": "usr_9f3a2b"
#     },
#     "status": "success",
#     "timestamp": "2024-05-01T10:30:00Z"
# }
หมายเหตุ:json.dumps() คืนค่า string สำหรับการเขียน JSON ที่จัดรูปแบบลง file โดยตรง ใช้ json.dump(data, f, indent=4) (ไม่มี s) — มันเขียนลง file object และหลีกเลี่ยง การสร้าง string ตัวกลางในหน่วยความจำ

ตารางอ้างอิงพารามิเตอร์ json.dumps()

พารามิเตอร์ทั้งหมดเป็นตัวเลือกยกเว้น object เอง ค่าเริ่มต้นสร้าง JSON ที่กระชับและปลอดภัยสำหรับ ASCII — ส่งพารามิเตอร์อย่างชัดเจนสำหรับผลลัพธ์ที่อ่านง่าย

พารามิเตอร์
ประเภท
ค่าเริ่มต้น
คำอธิบาย
obj
any
ออบเจกต์ Python ที่ต้องการ serialize เป็น string รูปแบบ JSON
indent
int | str | None
None
จำนวนช่องว่างต่อระดับการย่อหน้า None = บรรทัดเดียวกระชับ, 0 = ขึ้นบรรทัดใหม่เท่านั้น, 4 = มาตรฐาน
sort_keys
bool
False
เรียงคีย์ dictionary ตามตัวอักษรในทุกระดับที่ซ้อนกัน
ensure_ascii
bool
True
Escape อักขระ non-ASCII เป็น \uXXXX ตั้งค่าเป็น False เพื่อเก็บอักขระ Unicode ไว้ตามเดิม
separators
tuple | None
None
คู่ (sep_item, sep_key) ใช้ (",", ":") สำหรับผลลัพธ์ที่กระชับที่สุดโดยไม่มีช่องว่าง
default
callable | None
None
เรียกสำหรับประเภทที่ไม่สามารถ serialize ได้โดยปริยาย raise TypeError เพื่อปฏิเสธค่า
allow_nan
bool
True
Serialize float("nan") และ float("inf") เป็น JS literal ตั้งค่าเป็น False เพื่อ raise ValueError

ผลลัพธ์ JSON แบบกระชับด้วยพารามิเตอร์ separators

โดยค่าเริ่มต้น json.dumps() แยกรายการด้วย ", " และคีย์จากค่าด้วย ": ". พารามิเตอร์ separators แทนที่ทั้งคู่ การส่งผ่าน (',', ':') ลบช่องว่างทั้งหมดเพื่อสร้าง JSON ที่ถูกต้องและกระชับที่สุด — มีประโยชน์สำหรับ การส่งผ่านเครือข่าย การฝังใน URL หรือการเก็บ JSON ใน database column ที่ทุก byte มีความสำคัญ

Python 3.8+
import json

payload = {
    "endpoint": "/api/v2/events",
    "filters": {"status": "active", "limit": 100},
    "sort": "desc"
}

# ค่าเริ่มต้น — มีช่องว่างหลัง separator (อ่านง่าย)
default_out = json.dumps(payload)
# {"endpoint": "/api/v2/events", "filters": {"status": "active", "limit": 100}, "sort": "desc"}
# len = 88

# กระชับ — ไม่มีช่องว่างเลย
compact_out = json.dumps(payload, separators=(',', ':'))
# {"endpoint":"/api/v2/events","filters":{"status":"active","limit":100},"sort":"desc"}
# len = 80  (เล็กลง 9%; ประโยชน์เพิ่มขึ้นกับ payload ที่ซ้อนกันลึก)

# กระชับ + เรียงคีย์สำหรับ cache key หรือ content hash
canonical = json.dumps(payload, separators=(',', ':'), sort_keys=True)
print(canonical)
# {"endpoint":"/api/v2/events","filters":{"limit":100,"status":"active"},"sort":"desc"}
หมายเหตุ:เมื่อส่งผ่าน indent= พร้อมกับ separators=, อาร์กิวเมนต์ separators ควบคุมเฉพาะ separator inline — การขึ้นบรรทัดใหม่และการย่อหน้าจาก indent ยังคงอยู่ หากต้องการผลลัพธ์บรรทัดเดียวแบบกระชับ ให้ละ indent (หรือส่งผ่าน None) และตั้งค่า separators=(',', ':').

การ Serialize Python Object กำหนดเองด้วยพารามิเตอร์ default

module json มาตรฐาน serialize dict, list, string, ตัวเลข, boolean และ None — แต่ raiseTypeError สำหรับประเภทอื่น สาเหตุที่พบบ่อยที่สุดสองอย่างใน production code คือ object datetime และ UUID

Python 3.8+ — TypeError โดยไม่มีการจัดการกำหนดเอง
import json
from datetime import datetime, timezone
import uuid

order = {
    "order_id": uuid.uuid4(),             # ❌ TypeError: UUID is not JSON serializable
    "placed_at": datetime.now(timezone.utc),  # ❌ TypeError: datetime is not JSON serializable
    "total_thb": 4500.00,
    "items": ["pro-subscription", "addon-storage"]
}

json.dumps(order)  # raise TypeError

วิธีที่ 1 — พารามิเตอร์ default=

ส่งผ่าน callable ไปยัง default= json.dumps() จะเรียก มันสำหรับ object ใดก็ตามที่ไม่สามารถจัดการได้ คืนค่า representation ที่ serialize ได้ หรือ raise TypeError สำหรับประเภทที่ไม่รองรับ — อย่าเงียบกับประเภทที่ไม่รู้จัก

Python 3.8+
import json
from datetime import datetime, timezone, date
import uuid
from decimal import Decimal

def json_default(obj):
    if isinstance(obj, (datetime, date)):
        return obj.isoformat()
    if isinstance(obj, uuid.UUID):
        return str(obj)
    if isinstance(obj, Decimal):
        return float(obj)
    raise TypeError(f"ประเภท {type(obj).__name__!r} ไม่สามารถ serialize เป็น JSON ได้")

order = {
    "order_id": uuid.uuid4(),
    "placed_at": datetime(2024, 5, 1, 10, 30, 0, tzinfo=timezone.utc),
    "total_thb": Decimal("4500.00"),
    "items": ["pro-subscription", "addon-storage"]
}

print(json.dumps(order, indent=4, default=json_default))
# {
#     "order_id": "a3f1c2d4-e5b6-7890-abcd-ef1234567890",
#     "placed_at": "2024-05-01T10:30:00+00:00",
#     "total_thb": 4500.0,
#     "items": ["pro-subscription", "addon-storage"]
# }

วิธีที่ 2 — สืบทอด json.JSONEncoder

สำหรับ encoding logic ที่ใช้ซ้ำได้และแชร์ข้าม module หลายตัว การสืบทอด json.JSONEncoder สะอาดกว่าการส่งฟังก์ชัน default ไปทุกที่ Override method default และเรียก super().default(obj) เป็น fallback สุดท้าย — นี้รักษาพฤติกรรม error ที่ถูกต้องสำหรับประเภทที่ไม่รองรับ

Python 3.8+
import json
from datetime import datetime, timezone
import uuid
from decimal import Decimal

class AppEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.isoformat()
        if isinstance(obj, uuid.UUID):
            return str(obj)
        if isinstance(obj, Decimal):
            return float(obj)
        return super().default(obj)  # raise TypeError สำหรับประเภทที่ไม่รู้จัก

order = {
    "order_id": uuid.uuid4(),
    "placed_at": datetime(2024, 5, 1, 10, 30, 0, tzinfo=timezone.utc),
    "total_thb": Decimal("4500.00"),
}

# ส่ง encoder class ผ่าน cls=
print(json.dumps(order, indent=4, cls=AppEncoder))
# ผลลัพธ์เหมือนกับวิธี default= ข้างต้น
หมายเหตุ:เรียก super().default(obj) เสมอ (หรือ raise TypeError อย่างชัดเจน) สำหรับประเภทที่ไม่รู้จัก การคืนค่า str(obj) อย่างเงียบสำหรับทุกอย่างจะ ทำให้ object ที่ควร raise error เสียหาย — bug ที่ยากจะติดตามใน production

การถอดรหัสกลับ — object_hook

การ encode เป็นเพียงครึ่งเรื่อง เพื่อสร้าง Python object กำหนดเองจาก JSON ใหม่ ส่งฟังก์ชัน object_hook ไปยัง json.loads() หรือ json.load()hook จะถูกเรียกสำหรับทุก JSON object (dict) ที่ถอดรหัสและสามารถคืนค่า Python ใดก็ได้ แทน — ให้วงจร encode ↔ decode ที่สมบูรณ์

Python 3.8+
import json
from datetime import datetime
from dataclasses import dataclass

@dataclass
class Event:
    name: str
    occurred_at: datetime
    user_id: str

def encode_event(obj):
    if isinstance(obj, Event):
        return {
            "__type__": "Event",
            "name": obj.name,
            "occurred_at": obj.occurred_at.isoformat(),
            "user_id": obj.user_id,
        }
    raise TypeError(f"ไม่สามารถ serialize {type(obj)}")

def decode_event(d):
    if d.get("__type__") == "Event":
        return Event(
            name=d["name"],
            occurred_at=datetime.fromisoformat(d["occurred_at"]),
            user_id=d["user_id"],
        )
    return d

# Encode
event = Event("login", datetime(2024, 5, 1, 10, 30), "usr_9f3a2b")
json_str = json.dumps(event, default=encode_event, indent=4)

# ถอดรหัสกลับเป็น Event instance
restored = json.loads(json_str, object_hook=decode_event)
print(type(restored))           # <class 'Event'>
print(restored.occurred_at)     # 2024-05-01 10:30:00
หมายเหตุ:object_hook ถูกเรียกสำหรับทุก dict ที่ซ้อนกันใน document — ไม่ใช่แค่ระดับบนสุด รวม discriminator field (เช่น "__type__") เพื่อให้ hook แยกแยะ object กำหนดเองของคุณจาก dict ธรรมดาที่ควรปล่อยไว้ตามเดิม

pprint — Module ทางเลือก (และเมื่อไหรที่ไม่ควรใช้)

module pprint ของ Python (pretty printer) จัดรูปแบบโครงสร้างข้อมูล Python เพื่อให้อ่านง่ายใน terminal มันทำงานกับ Python object ที่ parse แล้ว ไม่ใช่ JSON string — และผลลัพธ์ ใช้ Python syntax ไม่ใช่ JSON syntax

Python 3.8+
import json, pprint

raw = '{"sensor_id":"s-441","readings":[23.1,23.4,22.9],"unit":"celsius","active":true}'
data = json.loads(raw)

# pprint — Python repr ที่ถูกต้อง ไม่ใช่ JSON ที่ถูกต้อง
pprint.pprint(data, sort_dicts=False)
# {'sensor_id': 's-441',
#  'readings': [23.1, 23.4, 22.9],
#  'unit': 'celsius',
#  'active': True}        ← Python True ไม่ใช่ JSON true

# json.dumps — JSON ที่ถูกต้อง
print(json.dumps(data, indent=4))
# {
#     "sensor_id": "s-441",
#     "readings": [23.1, 23.4, 22.9],
#     "unit": "celsius",
#     "active": true      ← JSON ที่ถูกต้อง
# }
คำเตือน:ห้ามส่งผลลัพธ์ pprint ไปยัง API endpoint หรือ เขียนลงไฟล์ .json เด็ดขาด — จะทำลาย JSON parser ใดก็ตามที่คาดหวัง standard syntax ใช้ json.dumps(indent=4) สำหรับผลลัพธ์ทั้งหมด ที่ต้องเป็น JSON ที่ถูกต้อง

เมื่อ pprint มีประโยชน์: การตรวจสอบ Python object อย่างรวดเร็วใน REPL หรือ debug log โดยเฉพาะเมื่อ object มีประเภทที่ไม่ serialize เป็น JSON ได้ (set, custom class instance, dataclass ก่อนการแปลง)

วิธีพิมพ์ JSON Response จาก Requests ให้สวยงาม

สถานการณ์จริงที่พบบ่อยที่สุด: คุณมีไฟล์ JSON บนดิสก์หรือ HTTP response จาก API และต้องการจัดรูปแบบเพื่อ debug หรือ logging ทั้งสองกรณี ใช้วิธีเดียวกัน — parse เป็น Python dict แล้วจัดรูปแบบด้วย json.dumps()

อ่านจากไฟล์

Python 3.8+
import json

try:
    with open("config.json", "r", encoding="utf-8") as f:
        data = json.load(f)

    # พิมพ์ให้สวยงามบน console
    print(json.dumps(data, indent=4, ensure_ascii=False))

    # หรือเขียนเวอร์ชันที่จัดรูปแบบแล้วกลับลงดิสก์
    with open("config.pretty.json", "w", encoding="utf-8") as f:
        json.dump(data, f, indent=4, ensure_ascii=False)

except json.JSONDecodeError as e:
    print(f"JSON ไม่ถูกต้อง: {e}")
except FileNotFoundError:
    print(f"ไม่พบไฟล์: config.json")

การจัดรูปแบบ API response

Python 3.8+ (ต้องการ: pip install requests)
import json, requests
from requests.exceptions import HTTPError, ConnectionError, Timeout

def pretty_print_api(url: str) -> None:
    try:
        resp = requests.get(url, timeout=10)
        resp.raise_for_status()
        print(json.dumps(resp.json(), indent=4, ensure_ascii=False))
    except HTTPError as e:
        print(f"HTTP {e.response.status_code}: {e}")
    except (ConnectionError, Timeout) as e:
        print(f"Network error: {e}")
    except json.JSONDecodeError:
        print(f"Response body ไม่ใช่ JSON:\n{resp.text[:500]}")

pretty_print_api("https://api.github.com/repos/python/cpython")
หมายเหตุ:response.json() parse response body แล้ว — ไม่จำเป็นต้องเรียก json.loads() แยกต่างหาก เพิ่ม raise_for_status() เสมอก่อนเข้าถึง .json() เพื่อจับ error 4xx/5xx ก่อนที่จะเกิด parse error ที่น่าสับสน

การพิมพ์ให้สวยงามจาก Command Line

Python มาพร้อมกับ json.tool, CLI module สำหรับจัดรูปแบบ JSON จาก terminal โดยตรง — ไม่ต้องเขียน Python script ใช้ได้บนเครื่องใดก็ตามที่ติดตั้ง Python

bash
# จัดรูปแบบไฟล์ local
python -m json.tool config.json

# Pipe API response ผ่าน formatter
curl -s https://api.github.com/users/gvanrossum | python -m json.tool

# จัดรูปแบบจาก stdin
echo '{"service":"api-gateway","version":"2.1.0","healthy":true}' | python -m json.tool

# เรียงคีย์ตามตัวอักษร
python -m json.tool --sort-keys data.json

# กำหนด indent เอง (Python 3.9+)
python -m json.tool --indent 2 data.json
หมายเหตุ:Python 3.9 เพิ่ม flag --indent และ --no-indent สำหรับการกรอง JSON บน terminal ที่มีประสิทธิภาพมากขึ้น พิจารณา jq — แต่ python -m json.tool ครอบคลุมการจัดรูปแบบ โดยไม่มี dependency เพิ่มเติม

ถ้าคุณไม่ได้อยู่ใน terminal เลย — วางการตอบกลับจาก Postman หรือไฟล์ log — JSON Formatter ของ ToolDeck ช่วยให้วาง จัดรูปแบบ และคัดลอกในขั้นตอนเดียว พร้อม syntax highlighting และการตรวจสอบที่ฝังอยู่

ไลบรารีทางเลือก: orjson และ rich

orjson — เร็วกว่า 5–10× พร้อมรองรับประเภท Native

module json มาตรฐานเร็วพอสำหรับส่วนใหญ่ แต่หาก serialize หลายพันออบเจกต์ต่อวินาที — logging pipeline, API throughput สูง, การส่งออกข้อมูลขนาดใหญ่ — orjson เร็วกว่า 5–10× มันรองรับประเภทที่ standard library ไม่สามารถ serialize ได้โดยไม่ต้องมีฟังก์ชัน default กำหนดเอง: datetime, uuid.UUID, numpy array และ dataclass

bash — ติดตั้ง
pip install orjson
Python 3.8+
import orjson
from datetime import datetime, timezone
import uuid

event = {
    "event_id": uuid.uuid4(),                  # ไม่ต้อง str() — orjson จัดการ UUID
    "timestamp": datetime.now(timezone.utc),   # ไม่ต้อง isoformat()
    "service": "auth-service",
    "level": "INFO",
    "payload": {
        "user_id": "usr_9f3a2b",
        "action": "login",
        "ip": "192.168.1.42",
        "latency_ms": 34
    }
}

# orjson.dumps คืนค่า bytes; .decode() แปลงเป็น str
print(orjson.dumps(event, option=orjson.OPT_INDENT_2).decode())
# {
#   "event_id": "a3f1c2d4-e5b6-7890-abcd-ef1234567890",
#   "timestamp": "2024-05-01T10:30:00+00:00",
#   "service": "auth-service",
#   ...
# }

สองสิ่งที่ควรรู้: orjson.dumps() คืนค่า bytes, ไม่ใช่ string — เรียก .decode() หากต้องการ string รองรับเฉพาะ 2-space indent ผ่าน OPT_INDENT_2; สำหรับผลลัพธ์ 4-space ใช้ json.dumps(indent=4) มาตรฐาน

rich — การไฮไลต์ Syntax บน Terminal

หากตรวจสอบ JSON บน terminal หรือ REPL เป็นประจำ rich แสดงผลแบบมีสีและไฮไลต์ syntax ที่ทำให้โครงสร้างที่ซ้อนกันลึกอ่านง่ายทันที คีย์ string ตัวเลข และ boolean แต่ละอย่างมีสีเฉพาะ — ง่ายกว่าการมองข้อความ monochrome มาก เป็นเครื่องมือ debug เท่านั้น ไม่ใช่สำหรับ production serialization

bash — ติดตั้ง
pip install rich
Python 3.8+
from rich import print_json
import json

# print_json() รับ JSON string
raw = '{"event":"login","user_id":"usr_9f3a2b","timestamp":"2024-05-01T10:30:00Z","success":true,"meta":{"ip":"192.168.1.42","attempts":1}}'
print_json(raw)

# สำหรับการพิมพ์ Python dict ให้สวยงาม แปลงเป็น string ก่อน
data = {
    "status": "success",
    "count": 42,
    "tags": ["python", "api", "backend"]
}
print_json(json.dumps(data))
คำเตือน:rich.print_json() ส่งออก ANSI escape codes สำหรับสี terminal — ห้ามนำผลลัพธ์นี้ไปเขียนลงไฟล์ .json หรือส่งเป็น API response เด็ดขาด ใช้ json.dumps(indent=4) สำหรับ ผลลัพธ์ที่เครื่องต้องอ่านได้

simplejson — การแทนที่แบบ Drop-in ที่รองรับ stdlib

simplejson คือไลบรารีที่กลายเป็น module json มาตรฐานของ Python — ยังคงได้รับการดูแลอย่างอิสระและนำหน้า stdlib ในฟีเจอร์เล็กน้อย เป็น drop-in replacement จริงๆ: เปลี่ยน import และ code ที่เหลือไม่เปลี่ยน มีประโยชน์เมื่อต้องการรองรับ Decimal โดยไม่ต้องใช้ encoder กำหนดเอง หรือเมื่อต้องการรองรับ Python เวอร์ชันเก่า

bash — ติดตั้ง
pip install simplejson
Python 3.8+
import simplejson as json  # API เหมือนกับ stdlib
from decimal import Decimal

order = {
    "item": "API subscription",
    "price": Decimal("149.99"),   # stdlib json raise TypeError ที่นี่
    "quantity": 3,
}

# simplejson serialize Decimal แบบ native — ไม่ต้องใช้ default=
print(json.dumps(order, indent=4, use_decimal=True))
# {
#     "item": "API subscription",
#     "price": 149.99,
#     "quantity": 3
# }
หมายเหตุ:สำหรับประสิทธิภาพที่ดีที่สุด orjson เป็นตัวเลือกที่ดีกว่า ใช้ simplejson เมื่อต้องการ serialize Decimal แบบ native โดยไม่เขียน encoder กำหนดเอง หรือเมื่อดูแล codebase ที่ใช้อยู่แล้ว

การประมวลผลไฟล์ JSON ขนาดใหญ่โดยไม่ใช้หน่วยความจำหมด

json.load() อ่านไฟล์ทั้งหมดเข้าหน่วยความจำก่อนที่คุณจะเข้าถึงฟิลด์เดียวได้ สำหรับไฟล์ ที่มีบันทึกหลายล้านรายการหรือ payload ที่เกินหนึ่งกิกะไบต์ จะทำให้เกิด MemoryError — หรืออย่างดีที่สุดบังคับให้ process ใช้ swap และทำงานช้า

Streaming ด้วย ijson

ijson คือ streaming JSON parser ที่สร้าง item ทีละรายการจาก file object คุณวนซ้ำผ่าน array element โดยไม่เก็บ dataset ทั้งหมดในหน่วยความจำ — หน่วยความจำสูงสุดเป็นสัดส่วนกับ object เดียว ไม่ใช่ขนาดไฟล์

bash — ติดตั้ง
pip install ijson
Python 3.8+
import ijson
from decimal import Decimal

# events.json โครงสร้าง: {"events": [...หลายล้าน object...]}
total_revenue = Decimal("0")
login_count = 0

with open("events.json", "rb") as f:   # ijson ต้องการ binary mode
    for event in ijson.items(f, "events.item"):
        if event.get("type") == "purchase":
            total_revenue += Decimal(str(event["amount_thb"]))
        elif event.get("type") == "login":
            login_count += 1

print(f"รายได้: {total_revenue:,.2f} THB  |  Logins: {login_count}")
# ประมวลผลไฟล์ 2 GB ด้วยหน่วยความจำสูงสุด ~30 MB
หมายเหตุ:เปลี่ยนจาก json.load() เป็น ijson เมื่อไฟล์เกินประมาณ 50–100 MB ต่ำกว่านั้น json.load() ง่ายกว่า และเร็วกว่ามากเพราะใช้ C-extension parser ภายใน เกิน 100 MB ประโยชน์การประหยัดหน่วยความจำจาก streaming มีน้ำหนักเกินค่าใช้จ่ายเพิ่มเติม

NDJSON — หนึ่ง JSON object ต่อบรรทัด

NDJSON (Newline Delimited JSON หรือที่เรียกว่า JSON Lines หรือ .jsonl) เก็บ JSON object ที่สมบูรณ์หนึ่งรายการต่อบรรทัด Log exporter, Kafka consumer และ data pipeline มักสร้างรูปแบบนี้เพราะแต่ละบรรทัดสามารถ append และอ่านได้อย่างอิสระ — ไม่ต้อง parse ทั้งไฟล์เพื่อเพิ่มบันทึก standard library จัดการได้โดยไม่มี dependency เพิ่ม

Python 3.8+
import json
from pathlib import Path

# เขียน NDJSON — หนึ่ง event ต่อบรรทัด
events = [
    {"ts": "2024-05-01T10:00:00Z", "user": "usr_9f3a2b", "action": "login"},
    {"ts": "2024-05-01T10:01:03Z", "user": "usr_9f3a2b", "action": "purchase", "sku": "pro-plan"},
    {"ts": "2024-05-01T10:15:42Z", "user": "usr_4ab1d9", "action": "login"},
]

with open("events.ndjson", "w", encoding="utf-8") as f:
    for event in events:
        f.write(json.dumps(event, ensure_ascii=False) + "\n")

# อ่าน NDJSON — หน่วยความจำคงที่ ไม่ว่าไฟล์จะใหญ่แค่ไหน
purchase_count = 0
with open("events.ndjson", "r", encoding="utf-8") as f:
    for line in f:
        line = line.strip()
        if not line:           # ข้ามบรรทัดว่าง
            continue
        event = json.loads(line)
        if event.get("action") == "purchase":
            purchase_count += 1
            print(f"{event['ts']} — {event['user']} ซื้อ {event['sku']}")

ข้อผิดพลาดที่พบบ่อย

ฉันเห็นข้อผิดพลาดสี่ข้อนี้ในเกือบทุก code review ที่เกี่ยวข้องกับ JSON serialization — โดยเฉพาะจาก developer ที่มาจาก JavaScript ที่ JSON.stringify จัดการ encoding โดยอัตโนมัติ

ใช้ print(data) แทน json.dumps()

ปัญหา: print() บน dict ใช้ Python repr — ผลลัพธ์แสดง True/None (Python syntax) ไม่ใช่ true/null (JSON syntax) ไม่ใช่ JSON ที่ถูกต้อง

วิธีแก้: ใช้ json.dumps(data, indent=4) เสมอสำหรับผลลัพธ์ JSON ที่ถูกต้องและอ่านง่าย

Before · Python
After · Python
data = {"active": True, "count": None}
print(data)
# {'active': True, 'count': None}
print(json.dumps(data, indent=4))
# {
#     "active": true,
#     "count": null
# }
ลืม ensure_ascii=False กับข้อความภาษาไทย

ปัญหา: อักขระพิเศษ (ตัวอักษรภาษาไทย, emoji) ถูก escape เป็นลำดับ \\uXXXX ทำให้ผลลัพธ์อ่านไม่ออก

วิธีแก้: ส่งผ่าน ensure_ascii=False เพื่อเก็บอักขระ Unicode ดั้งเดิม

Before · Python
After · Python
user = {"name": "สมชาย ใจดี", "city": "กรุงเทพ"}
json.dumps(user, indent=2)
# {"name": "\u0e2a\u0e21\u0e0a\u0e32\u0e22...", "city": "\u0e01\u0e23\u0e38..."}
json.dumps(user, indent=2, ensure_ascii=False)
# {"name": "สมชาย ใจดี", "city": "กรุงเทพ"}
ใช้ json.dumps() สำหรับเขียนลงไฟล์

ปัญหา: json.dumps() คืนค่า string; จากนั้นต้องเรียก f.write() แยกต่างหาก สร้าง string ตัวกลางที่ไม่จำเป็น

วิธีแก้: ใช้ json.dump(data, f, indent=4) — เขียนลง file object โดยตรง

Before · Python
After · Python
with open("out.json", "w") as f:
    f.write(json.dumps(data, indent=4))
with open("out.json", "w", encoding="utf-8") as f:
    json.dump(data, f, indent=4, ensure_ascii=False)
ใช้ pprint แล้วคาดว่าจะได้ JSON ที่ถูกต้อง

ปัญหา: pprint.pprint() ใช้ Python syntax (True, None, single quotes) ที่ JSON parser ปฏิเสธ

วิธีแก้: ใช้ json.dumps(indent=4) สำหรับผลลัพธ์ใดก็ตามที่ต้อง parse เป็น JSON ได้

Before · Python
After · Python
import pprint
pprint.pprint({"running": True, "last_error": None})
# {'running': True, 'last_error': None}
import json
print(json.dumps({"running": True, "last_error": None}, indent=4))
# {"running": true, "last_error": null}

การเปรียบเทียบวิธีการ — json.dumps, orjson, simplejson, rich

ใช้ json.dumps() สำหรับการจัดรูปแบบประจำวันและการเขียนไฟล์ — ครอบคลุม 95% ของ use case โดยไม่มี dependency เลือกใช้ orjson เมื่อ serialize ใน hot path หรือเมื่อ object มีฟิลด์ datetime และ UUIDใช้ simplejson เมื่อต้องการ drop-in ที่รองรับ stdlib พร้อม Decimal สำเร็จรูป จำกัดการใช้ rich.print_json() และ pprint เฉพาะสำหรับการตรวจสอบ terminal ในพื้นที่ — ทั้งสองไม่สร้างผลลัพธ์ที่เครื่องอ่านได้

วิธีการ
ผลลัพธ์
JSON ถูกต้อง
ความเร็ว
Non-ASCII
ประเภทกำหนดเอง
การติดตั้ง
json.dumps(indent=4)
String
มาตรฐาน
ensure_ascii=False
default= / JSONEncoder
มีในตัว
json.dump(f, indent=4)
File
มาตรฐาน
ensure_ascii=False
default= / JSONEncoder
มีในตัว
pprint.pprint()
Python repr
มาตรฐาน
Native
✅ (repr ใดก็ได้)
มีในตัว
orjson.dumps(OPT_INDENT_2)
Bytes
เร็วกว่า 5–10×
Native
datetime, UUID, numpy
pip install orjson
python -m json.tool
stdout CLI
มาตรฐาน
มีในตัว
simplejson.dumps()
String
เร็วกว่า ~1.5×
ensure_ascii=False
Decimal แบบ native
pip install simplejson
rich.print_json()
Terminal เท่านั้น
✅ (input)
มาตรฐาน
pip install rich

คำถามที่พบบ่อย

จะพิมพ์ JSON ให้สวยงามใน Python ได้อย่างไร?

เรียก json.dumps(data, indent=4) พารามิเตอร์ indent กำหนดจำนวนช่องว่างต่อระดับการซ้อน import module json ก่อน — มาพร้อมกับ standard library ของ Python ไม่ต้อง pip install ส่งผ่าน ensure_ascii=False หากข้อมูลมีอักขระ non-ASCII เช่น ตัวอักษรภาษาไทยหรืออักษร CJK

python
import json

phuchai = {"username": "somchai", "plan": "enterprise", "permissions": ["read", "write", "deploy"]}
print(json.dumps(phuchai, indent=4, ensure_ascii=False))

ความแตกต่างระหว่าง json.dumps() และ json.dump() คืออะไร?

json.dumps() (มีตัว "s") คืนค่า string ที่จัดรูปแบบแล้วในหน่วยความจำ json.dump() (ไม่มี "s") เขียนลง file-like object โดยตรง — ส่ง file handle ที่เปิดอยู่เป็นอาร์กิวเมนต์ที่สอง สำหรับการเขียน JSON ที่จัดรูปแบบลงดิสก์ json.dump(data, f, indent=4) เป็นวิธีที่นิยมและหลีกเลี่ยงการสร้าง string ตัวกลาง

python
# dumps → string ในหน่วยความจำ
formatted = json.dumps(data, indent=4)

# dump → เขียนลง file โดยตรง
with open('output.json', 'w', encoding='utf-8') as f:
    json.dump(data, f, indent=4)

ทำไม json.dumps() แสดง \u0e2a\u0e27\u0e31 แทนที่จะเป็นตัวอักษรจริง?

โดยค่าเริ่มต้น ensure_ascii=True จะ escape อักขระ non-ASCII ทุกตัวเป็นลำดับ \uXXXX ตั้งค่า ensure_ascii=False เพื่อเก็บอักขระ Unicode ดั้งเดิม สิ่งนี้สำคัญมากสำหรับชื่อคน ที่อยู่ และเนื้อหาที่ผู้ใช้สร้างขึ้นในภาษาไทยหรือภาษาที่ไม่ใช้ตัวอักษรละติน

python
data = {"mueang": "กรุงเทพ", "salam": "สวัสดี", "prathet": "ไทย"}

# ค่าเริ่มต้น — ถูก escape
json.dumps(data, indent=4)
# {"mueang": "\u0e01\u0e23\u0e38\u0e07\u0e40\u0e17\u0e1e", ...}

# อ่านได้
json.dumps(data, indent=4, ensure_ascii=False)
# {"mueang": "กรุงเทพ", "salam": "สวัสดี", "prathet": "ไทย"}

จะพิมพ์ JSON string (ไม่ใช่ dict) ให้สวยงามได้อย่างไร?

ก่อนอื่น parse string ด้วย json.loads() แล้วจัดรูปแบบด้วย json.dumps() การเรียกสองครั้งสามารถเชื่อมต่อกันในบรรทัดเดียวสำหรับการตรวจสอบบน terminal อย่างรวดเร็ว

python
import json

raw = '{"endpoint":"/api/v2/users","timeout":30,"retry":true}'
print(json.dumps(json.loads(raw), indent=4))

ใช้ pprint จัดรูปแบบ JSON ใน Python ได้ไหม?

pprint.pprint() สร้าง Python object representation ไม่ใช่ JSON ที่ถูกต้อง ใช้ True/False/None (Python syntax) แทน true/false/null (JSON syntax) อย่าส่ง pprint output ไปยัง API หรือ JSON parser เด็ดขาด — ใช้ json.dumps(indent=4) สำหรับทุกสิ่งที่ต้องเป็น JSON ที่ถูกต้อง

python
import pprint, json

data = {"active": True, "score": None}

pprint.pprint(data)     # {'active': True, 'score': None}  ← ไม่ใช่ JSON
json.dumps(data, indent=4)  # {"active": true, "score": null}  ← JSON ถูกต้อง

จะเรียงคีย์ JSON ตามตัวอักษรใน Python ได้อย่างไร?

เพิ่ม sort_keys=True ใน json.dumps() สำหรับ command line ใช้ python -m json.tool --sort-keys data.json คีย์ที่เรียงแล้วทำให้ JSON diff อ่านง่ายและช่วยระบุค่าที่เปลี่ยนแปลงได้รวดเร็ว

python
import json

server = {"workers": 4, "host": "0.0.0.0", "port": 8080, "debug": False}
print(json.dumps(server, indent=4, sort_keys=True))
# {
#     "debug": false,
#     "host": "0.0.0.0",
#     "port": 8080,
#     "workers": 4
# }

Python ให้การควบคุมเต็มรูปแบบ — custom serializers, streaming, การรวม pipeline เมื่อต้องการตรวจสอบหรือแชร์ snippet ที่จัดรูปแบบแล้ว JSON Formatter ของ ToolDeck คือเส้นทางที่เร็วกว่า: วาง JSON แล้วรับผลลัพธ์ที่เยื้องและไฮไลต์โดยไม่ต้องตั้งค่าสภาพแวดล้อม

เครื่องมือที่เกี่ยวข้อง

มีให้ในภาษาอื่นด้วย:GoJavaScriptBash
MS
Maria SantosBackend Developer

Maria is a backend developer specialising in Python and API integration. She has broad experience with data pipelines, serialisation formats, and building reliable server-side services. She is an active member of the Python community and enjoys writing practical, example-driven guides that help developers solve real problems without unnecessary theory.

DV
Dmitri Volkovผู้ตรวจสอบทางเทคนิค

Dmitri is a DevOps engineer who relies on Python as his primary scripting and automation language. He builds internal tooling, CI/CD pipelines, and infrastructure automation scripts that run in production across distributed teams. He writes about the Python standard library, subprocess management, file processing, encoding utilities, and the practical shell-adjacent Python that DevOps engineers use every day.