JSON Formatter Python โ€” Panduan json.dumps()

ยทBackend DeveloperยทDitinjau olehDmitri VolkovยทDiterbitkan

Gunakan JSON Formatter & Beautifier gratis langsung di browser Anda โ€” tidak perlu instalasi.

Coba JSON Formatter & Beautifier Online โ†’

Saat saya men-debug klien Python API, hal pertama yang saya gunakan adalah pretty print json python โ€” satu panggilan ke json.dumps(data, indent=4) dan blob satu baris yang tidak terbaca langsung menjadi mudah dinavigasi. Modul bawaan json Python menangani ini sepenuhnya di library standar โ€” tidak perlu instalasi pihak ketiga. Jika hanya butuh hasil cepat tanpa menulis kode, JSON Formatter dari ToolDeck melakukannya secara instan. Panduan ini mencakup setiap metode praktis: json.dumps() dengan semua parameternya, pprint, orjson untuk pemformatan berkinerja tinggi, json.tool CLI, dan skenario dunia nyata seperti memformat respons API dan membaca dari disk โ€” semuanya dengan kode yang kompatibel Python 3.8+. Juga mencakup serialisasi tipe kustom seperti datetime dan UUID, streaming file berukuran gigabyte dengan ijson, dan penyorotan sintaks terminal dengan rich.

Poin Utama
  • โ†’json.dumps(data, indent=4) sudah bawaan di stdlib Python sejak versi 2.6 โ€” tidak perlu instalasi.
  • โ†’Sertakan ensure_ascii=False setiap kali data Anda mengandung huruf beraksen, karakter CJK, atau emoji.
  • โ†’Untuk datetime, UUID, atau kelas kustom, gunakan parameter default= atau subclass json.JSONEncoder.
  • โ†’separators=(',', ':') menghapus semua spasi โ€” gunakan untuk transfer jaringan atau embedding URL.
  • โ†’orjson 5โ€“10ร— lebih cepat dari stdlib dan secara native menangani datetime dan uuid.UUID.
  • โ†’pprint.pprint() menghasilkan sintaks Python (True/None), bukan JSON valid โ€” jangan pernah gunakan untuk file atau respons API.
  • โ†’Untuk file JSON lebih besar dari 50 MB, streaming dengan ijson daripada json.load() untuk menghindari MemoryError.

Apa Itu Pretty Printing JSON?

Pretty printing mengubah string JSON yang padat dan diminifikasi menjadi format yang mudah dibaca dengan indentasi yang konsisten dan jeda baris. Transformasi ini murni kosmetik: datanya identik, hanya presentasinya yang berubah. Modul json Python menangani ini sepenuhnya di library standar โ€” tidak perlu menginstal apapun.

Before ยท json
After ยท json
{"id":"usr_9f3a2b","name":"Budi Santoso","roles":["admin","editor"],"prefs":{"theme":"dark","lang":"id"}}
{
    "id": "usr_9f3a2b",
    "name": "Budi Santoso",
    "roles": [
        "admin",
        "editor"
    ],
    "prefs": {
        "theme": "dark",
        "lang": "id"
    }
}

json.dumps() โ€” Cara Standar Memformat JSON

json.dumps() adalah bagian dari library standar Python sejak Python 2.6 โ€” cukup import json, tidak perlu instalasi. Ia menserialisasi objek Python yang kompatibel JSON ke string terformat. Parameter kuncinya adalah indent: atur ke 4 (atau 2) untuk mendapatkan output yang mudah dibaca.

Python 3.8+ โ€” contoh minimal
import json

user = {
    "id": "usr_9f3a2b",
    "name": "Budi Santoso",
    "roles": ["admin", "editor"],
    "prefs": {"theme": "dark", "lang": "id"}
}

print(json.dumps(user, indent=4))
# Output:
# {
#     "id": "usr_9f3a2b",
#     "name": "Budi Santoso",
#     "roles": [
#         "admin",
#         "editor"
#     ],
#     "prefs": {
#         "theme": "dark",
#         "lang": "id"
#     }
# }

Untuk penggunaan produksi, Anda sering ingin sort_keys=True (output konsisten antar run) dan ensure_ascii=False (mempertahankan karakter non-ASCII agar mudah dibaca):

Python 3.8+ โ€” dengan sort_keys dan ensure_ascii
import json

api_response = {
    "timestamp": "2024-05-01T10:30:00Z",
    "status": "success",
    "data": {
        "user_id": "usr_9f3a2b",
        "display_name": "Sari Dewi",
        "kota": "Jakarta",
        "score": 4892.5,
        "tags": ["python", "backend", "api"]
    }
}

print(json.dumps(api_response, indent=4, sort_keys=True, ensure_ascii=False))
# Output (kunci diurutkan):
# {
#     "data": {
#         "display_name": "Sari Dewi",
#         "kota": "Jakarta",
#         "score": 4892.5,
#         "tags": ["api", "backend", "python"],
#         "user_id": "usr_9f3a2b"
#     },
#     "status": "success",
#     "timestamp": "2024-05-01T10:30:00Z"
# }
Catatan:json.dumps() mengembalikan string. Untuk menulis JSON terformat langsung ke file, gunakan json.dump(data, f, indent=4) (tanpa s) โ€” ia menulis ke objek file dan menghindari pembuatan string perantara di memori.

Referensi Parameter json.dumps()

Semua parameter bersifat opsional kecuali objeknya sendiri. Default menghasilkan JSON padat yang aman untuk ASCII โ€” sertakan parameter secara eksplisit untuk output yang mudah dibaca manusia.

Parameter
Tipe
Default
Deskripsi
obj
any
โ€”
Objek Python yang akan diserialisasi menjadi string berformat JSON.
indent
int | str | None
None
Spasi per level indentasi. None = satu baris padat, 0 = hanya baris baru, 4 = standar.
sort_keys
bool
False
Mengurutkan kunci dictionary secara alfabet di semua level bertingkat.
ensure_ascii
bool
True
Escape karakter non-ASCII ke \uXXXX. Set False untuk mempertahankan karakter Unicode asli.
separators
tuple | None
None
Pasangan (sep_item, sep_kunci). Gunakan (",", ":") untuk output paling padat tanpa spasi.
default
callable | None
None
Dipanggil untuk tipe yang tidak bisa diserialisasi. Lempar TypeError untuk menolak nilai.
allow_nan
bool
True
Serialisasi float("nan") dan float("inf") sebagai literal JS. Set False untuk melempar ValueError.

Output JSON Padat dengan Parameter separators

Secara default json.dumps() memisahkan item dengan ", " dan kunci dari nilai dengan ": ". Parameter separators mengganti keduanya. Meneruskan (',', ':') menghapus semua spasi untuk menghasilkan JSON valid yang paling padat โ€” berguna untuk transmisi jaringan, embedding URL, atau menyimpan JSON di kolom database di mana setiap byte diperhitungkan.

Python 3.8+
import json

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

# Default โ€” spasi setelah pemisah (mudah dibaca)
default_out = json.dumps(payload)
# {"endpoint": "/api/v2/events", "filters": {"status": "active", "limit": 100}, "sort": "desc"}
# len = 88

# Padat โ€” tanpa spasi sama sekali
compact_out = json.dumps(payload, separators=(',', ':'))
# {"endpoint":"/api/v2/events","filters":{"status":"active","limit":100},"sort":"desc"}
# len = 80  (9% lebih kecil; penghematan semakin besar pada payload yang lebih besar dan dalam)

# Padat + kunci terurut untuk cache key yang dapat direproduksi
canonical = json.dumps(payload, separators=(',', ':'), sort_keys=True)
print(canonical)
# {"endpoint":"/api/v2/events","filters":{"limit":100,"status":"active"},"sort":"desc"}
Catatan:Saat meneruskan indent= bersama separators=, argumen separators hanya mengontrol pemisah inline โ€” jeda baris dan indentasi dari indent tetap dipertahankan. Jika ingin output padat satu baris, hilangkan indent (atau sertakan None) dan set separators=(',', ':').

Serialisasi Objek Python Kustom dengan Parameter default

Modul json standar menserialisasi dict, list, string, angka, boolean, dan None โ€” tetapi melemparTypeError untuk tipe lainnya. Dua pelanggar paling umum dalam kode produksi adalah objek datetime dan UUID.

Python 3.8+ โ€” TypeError tanpa penanganan kustom
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_idr": 2250000,
    "items": ["pro-subscription", "addon-storage"]
}

json.dumps(order)  # melempar TypeError

Pendekatan 1 โ€” parameter default=

Sertakan callable ke default=. json.dumps() memanggilnya untuk objek yang tidak bisa ditangani. Kembalikan representasi yang bisa diserialisasi, atau lempar TypeError untuk tipe yang tidak Anda dukung secara eksplisit โ€” jangan pernah diam-diam mengabaikan tipe yang tidak dikenal.

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 {type(obj).__name__!r} is not JSON serializable")

order = {
    "order_id": uuid.uuid4(),
    "placed_at": datetime(2024, 5, 1, 10, 30, 0, tzinfo=timezone.utc),
    "total_idr": Decimal("2250000"),
    "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_idr": 2250000.0,
#     "items": ["pro-subscription", "addon-storage"]
# }

Pendekatan 2 โ€” subclass json.JSONEncoder

Untuk logika encoding yang dapat digunakan kembali dan dibagikan di beberapa modul, membuat subclass json.JSONEncoder lebih bersih daripada meneruskan fungsi default ke mana-mana. Override metode default dan panggil super().default(obj) sebagai fallback terakhir โ€” ini mempertahankan perilaku error yang benar untuk tipe yang tidak didukung.

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)  # melempar TypeError untuk tipe tidak dikenal

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

# Sertakan kelas encoder via cls=
print(json.dumps(order, indent=4, cls=AppEncoder))
# Output identik dengan pendekatan default=
Catatan:Selalu panggil super().default(obj) (atau lempar TypeError secara eksplisit) untuk tipe yang tidak dikenali. Diam-diam mengembalikan str(obj) untuk segalanya akan merusak objek yang seharusnya melempar error โ€” bug yang sulit dilacak di produksi.

Decoding kembali โ€” object_hook

Encoding hanya separuh cerita. Untuk merekonstruksi objek Python kustom dari JSON, sertakan fungsi object_hook ke json.loads() atau json.load(). Hook dipanggil untuk setiap objek JSON (dict) yang di-decode dan bisa mengembalikan nilai Python apapun sebagai gantinya โ€” memberi Anda siklus encode โ†” decode yang lengkap.

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

# Decode kembali ke instance Event
restored = json.loads(json_str, object_hook=decode_event)
print(type(restored))           # <class 'Event'>
print(restored.occurred_at)     # 2024-05-01 10:30:00
Catatan:object_hook dipanggil untuk setiap dict bertingkat dalam dokumen โ€” bukan hanya level teratas. Sertakan field discriminator (seperti "__type__") agar hook bisa membedakan objek kustom Anda dari dict biasa yang harus dibiarkan apa adanya.

pprint โ€” Modul Alternatif (dan Kapan Tidak Menggunakannya)

Modul pprint Python (pretty printer) memformat struktur data Python agar mudah dibaca di terminal. Ia bekerja pada objek Python yang telah di-parse, bukan pada string JSON โ€” dan outputnya menggunakan sintaks Python, bukan sintaks JSON.

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 โ€” repr Python valid, BUKAN JSON valid
pprint.pprint(data, sort_dicts=False)
# {'sensor_id': 's-441',
#  'readings': [23.1, 23.4, 22.9],
#  'unit': 'celsius',
#  'active': True}        โ† Python True, bukan JSON true

# json.dumps โ€” JSON valid
print(json.dumps(data, indent=4))
# {
#     "sensor_id": "s-441",
#     "readings": [23.1, 23.4, 22.9],
#     "unit": "celsius",
#     "active": true      โ† JSON valid
# }
Peringatan:Jangan pernah mengirim output pprint ke endpoint API atau menulisnya ke file .json โ€” ini akan merusak parser JSON manapun yang mengharapkan sintaks standar. Gunakan json.dumps(indent=4) untuk semua output yang harus berupa JSON valid.

Kapan pprint masuk akal: inspeksi cepat terminal objek Python di REPL atau log debug, terutama ketika objek mengandung tipe yang tidak bisa diserialisasi JSON (set, instance kelas kustom, dataclass sebelum konversi).

Cara Pretty Print Respons JSON dari Requests

Skenario dunia nyata yang paling umum: Anda memiliki file JSON di disk atau respons HTTP dari API, dan ingin memformatnya untuk debugging atau logging. Kedua kasus menggunakan pendekatan yang sama โ€” parse ke dict Python, lalu format dengan json.dumps().

Membaca dari file

Python 3.8+
import json

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

    # Pretty-print ke konsol
    print(json.dumps(data, indent=4, ensure_ascii=False))

    # Atau tulis versi terformat kembali ke disk
    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 tidak valid: {e}")
except FileNotFoundError:
    print(f"File tidak ditemukan: config.json")

Memformat respons API

Python 3.8+ (memerlukan: 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"Error jaringan: {e}")
    except json.JSONDecodeError:
        print(f"Body respons bukan JSON:\n{resp.text[:500]}")

pretty_print_api("https://api.github.com/repos/python/cpython")
Catatan:response.json() sudah mem-parse body respons โ€” tidak perlu memanggil json.loads() secara terpisah. Selalu tambahkan raise_for_status() sebelum mengakses .json() untuk menangkap error 4xx/5xx sebelum menyebabkan error parse yang membingungkan.

Pretty Printing dari Command Line

Python hadir dengan json.tool, modul CLI untuk memformat JSON langsung dari terminal โ€” tidak perlu script Python. Tersedia di mesin manapun yang memiliki Python terinstal.

bash
# Format file lokal
python -m json.tool config.json

# Pipe respons API melalui formatter
curl -s https://api.github.com/users/gvanrossum | python -m json.tool

# Format dari stdin
echo '{"service":"api-gateway","version":"2.1.0","healthy":true}' | python -m json.tool

# Urutkan kunci secara alfabet
python -m json.tool --sort-keys data.json

# Indentasi kustom (Python 3.9+)
python -m json.tool --indent 2 data.json
Catatan:Python 3.9 menambahkan flag --indent dan --no-indent. Untuk filtering JSON yang lebih canggih di terminal, pertimbangkan jq โ€” tetapi python -m json.tool sudah mencakup use case formatting tanpa dependensi tambahan.

Jika Anda tidak berada di terminal sama sekali โ€” menempel respons dari Postman atau file log โ€” JSON Formatter ToolDeck memungkinkan Anda menempel, memformat, dan menyalin dalam satu langkah dengan syntax highlighting dan validasi bawaan.

Library Alternatif: orjson dan rich

orjson โ€” 5โ€“10ร— Lebih Cepat dengan Dukungan Tipe Native

Modul json standar cukup cepat untuk sebagian besar use case, tetapi jika Anda menserialisasi ribuan objek per detik โ€” pipeline logging, API throughput tinggi, ekspor data besar โ€” orjson 5โ€“10ร— lebih cepat. Ia juga secara native menangani tipe yang tidak bisa diserialisasi library standar tanpa fungsi default kustom: datetime, uuid.UUID, array numpy, dan dataclass.

bash โ€” instal
pip install orjson
Python 3.8+
import orjson
from datetime import datetime, timezone
import uuid

event = {
    "event_id": uuid.uuid4(),                  # tidak perlu str() โ€” orjson tangani UUID
    "timestamp": datetime.now(timezone.utc),   # tidak perlu isoformat()
    "service": "auth-service",
    "level": "INFO",
    "payload": {
        "user_id": "usr_9f3a2b",
        "action": "login",
        "ip": "192.168.1.42",
        "latency_ms": 34
    }
}

# orjson.dumps mengembalikan bytes; .decode() mengubah ke 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",
#   ...
# }

Dua hal yang perlu diketahui: orjson.dumps() mengembalikan bytes, bukan string โ€” panggil .decode() jika Anda butuh string. Hanya mendukung indentasi 2 spasi via OPT_INDENT_2; untuk output 4 spasi gunakan json.dumps(indent=4) standar.

rich โ€” Penyorotan Sintaks di Terminal

Jika Anda secara rutin memeriksa JSON di terminal atau REPL, rich merender output berwarna dengan penyorotan sintaks yang membuat struktur bertingkat dalam mudah dibaca sekilas. Kunci, string, angka, dan boolean masing-masing mendapat warna berbeda โ€” jauh lebih mudah dipindai daripada dinding teks monokrom. Ini adalah alat waktu debug saja, bukan untuk serialisasi produksi.

bash โ€” instal
pip install rich
Python 3.8+
from rich import print_json
import json

# print_json() menerima string JSON
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)

# Untuk pretty-print dict Python, konversi ke string terlebih dahulu
data = {
    "status": "success",
    "count": 42,
    "tags": ["python", "api", "backend"]
}
print_json(json.dumps(data))
Peringatan:rich.print_json() menghasilkan escape code ANSI untuk warna terminal โ€” jangan pernah menangkap output ini dan menulisnya ke file .json atau mengirimnya sebagai respons API. Gunakan json.dumps(indent=4) untuk semua output yang bisa dibaca mesin.

simplejson โ€” Pengganti Kompatibel untuk stdlib

simplejson adalah library yang menjadi modul json standar Python โ€” masih dipelihara secara independen dan unggul dari stdlib dalam fitur minor. Ini adalah pengganti drop-in yang benar: ganti import dan sisa kode Anda tidak berubah. Berguna ketika Anda membutuhkan dukungan Decimal tanpa encoder kustom, atau ketika menargetkan lingkungan Python yang lebih lama.

bash โ€” instal
pip install simplejson
Python 3.8+
import simplejson as json  # API identik dengan stdlib
from decimal import Decimal

order = {
    "item": "API subscription",
    "price": Decimal("49.99"),   # stdlib json melempar TypeError di sini
    "quantity": 3,
}

# simplejson menserialisasi Decimal secara native โ€” tidak perlu default=
print(json.dumps(order, indent=4, use_decimal=True))
# {
#     "item": "API subscription",
#     "price": 49.99,
#     "quantity": 3
# }
Catatan:Untuk performa murni, orjson adalah pilihan yang lebih baik. Gunakan simplejson ketika Anda membutuhkan serialisasiDecimal native tanpa menulis encoder kustom, atau ketika memelihara codebase yang sudah menggunakannya.

Memproses File JSON Besar Tanpa Kehabisan Memori

json.load() membaca seluruh file ke memori sebelum Anda bisa mengakses satu field pun. Pada file dengan jutaan record atau payload di atas satu gigabyte, ini menyebabkan MemoryError โ€” atau paling baiknya memaksa proses beralih ke disk dan berjalan lambat.

Streaming dengan ijson

ijson adalah parser JSON streaming yang menghasilkan item satu per satu dari objek file. Anda mengiterasi elemen array tanpa pernah menyimpan dataset penuh di memori โ€” puncak memori tetap proporsional dengan satu objek, bukan ukuran file.

bash โ€” instal
pip install ijson
Python 3.8+
import ijson
from decimal import Decimal

# events.json struktur: {"events": [...jutaan objek...]}
total_revenue = Decimal("0")
login_count = 0

with open("events.json", "rb") as f:   # ijson memerlukan mode biner
    for event in ijson.items(f, "events.item"):
        if event.get("type") == "purchase":
            total_revenue += Decimal(str(event["amount_idr"]))
        elif event.get("type") == "login":
            login_count += 1

print(f"Revenue: Rp{total_revenue:.0f}  |  Logins: {login_count}")
# Memproses file 2 GB dengan ~30 MB puncak penggunaan memori
Catatan:Beralih dari json.load() ke ijson ketika file Anda melebihi sekitar 50โ€“100 MB. Di bawah ambang batas itu json.load() lebih sederhana dan jauh lebih cepat karena menggunakan parser ekstensi C secara internal. Di atas 100 MB, penghematan memori dari streaming melebihi overhead tambahan.

NDJSON โ€” satu objek JSON per baris

NDJSON (Newline Delimited JSON, juga disebut JSON Lines atau .jsonl) menyimpan satu objek JSON lengkap per baris. Eksporter log, konsumen Kafka, dan pipeline data sering menghasilkan format ini karena setiap baris bisa ditambahkan dan dibaca secara independen โ€” tidak perlu mem-parse seluruh file untuk menambah record. Library standar menanganinya tanpa dependensi tambahan.

Python 3.8+
import json
from pathlib import Path

# Tulis NDJSON โ€” satu event per baris
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")

# Baca NDJSON โ€” memori konstan, berapapun ukuran file
purchase_count = 0
with open("events.ndjson", "r", encoding="utf-8") as f:
    for line in f:
        line = line.strip()
        if not line:           # lewati baris kosong
            continue
        event = json.loads(line)
        if event.get("action") == "purchase":
            purchase_count += 1
            print(f"{event['ts']} โ€” {event['user']} membeli {event['sku']}")

Kesalahan Umum

Saya telah melihat empat kesalahan ini di hampir setiap code review yang melibatkan serialisasi JSON โ€” terutama dari developer yang datang dari JavaScript di mana JSON.stringify menangani encoding secara otomatis.

โŒ Kesalahan: Menggunakan print(data) alih-alih json.dumps()

Masalah: print() pada dict menggunakan repr Python โ€” output menampilkan True/None (sintaks Python), bukan true/null (sintaks JSON). Ini bukan JSON valid.

Solusi: Selalu gunakan json.dumps(data, indent=4) untuk output JSON yang valid dan mudah dibaca.

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
# }
โŒ Kesalahan: Lupa ensure_ascii=False dengan teks non-ASCII

Masalah: Karakter khusus (huruf beraksen, CJK, emoji) di-escape ke urutan \\uXXXX, membuat output tidak terbaca.

Solusi: Sertakan ensure_ascii=False untuk mempertahankan karakter Unicode asli.

Before ยท Python
After ยท Python
user = {"name": "Sari Dewi", "kota": "Surabaya"}
json.dumps(user, indent=2)
# {"name": "Sari Dewi", "kota": "Surabaya"}
json.dumps(user, indent=2, ensure_ascii=False)
# {"name": "Sari Dewi", "kota": "Surabaya"}
โŒ Kesalahan: Menggunakan json.dumps() untuk menulis ke file

Masalah: json.dumps() mengembalikan string; Anda kemudian membutuhkan panggilan f.write() terpisah, membuat string perantara yang tidak perlu.

Solusi: Gunakan json.dump(data, f, indent=4) โ€” ia menulis langsung ke objek file.

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)
โŒ Kesalahan: Pretty-printing dengan pprint dan mengharapkan JSON valid

Masalah: pprint.pprint() menggunakan sintaks Python (True, None, tanda kutip tunggal) yang ditolak parser JSON.

Solusi: Gunakan json.dumps(indent=4) untuk output apapun yang harus bisa di-parse sebagai 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}

Perbandingan Metode โ€” json.dumps, orjson, simplejson, rich

Gunakan json.dumps() untuk pemformatan sehari-hari dan penulisan file โ€” mencakup 95% use case tanpa dependensi. Gunakan orjson saat menserialisasi di hot path atau objek Anda menyertakan field datetime dan UUID. Gunakan simplejson ketika membutuhkan kompatibilitas drop-in stdlib dengan dukungan Decimal siap pakai. Simpan rich.print_json() dan pprint hanya untuk inspeksi terminal lokal โ€” keduanya tidak menghasilkan output yang bisa dibaca mesin.

Metode
Output
JSON Valid
Kecepatan
Non-ASCII
Tipe Kustom
Instalasi
json.dumps(indent=4)
String
โœ…
Standar
ensure_ascii=False
default= / JSONEncoder
Bawaan
json.dump(f, indent=4)
File
โœ…
Standar
ensure_ascii=False
default= / JSONEncoder
Bawaan
pprint.pprint()
repr Python
โŒ
Standar
Native
โœ… (repr apapun)
Bawaan
orjson.dumps(OPT_INDENT_2)
Bytes
โœ…
5โ€“10ร— lebih cepat
Native
datetime, UUID, numpy
pip install orjson
python -m json.tool
stdout CLI
โœ…
Standar
โœ…
โŒ
Bawaan
simplejson.dumps()
String
โœ…
~1.5ร— lebih cepat
ensure_ascii=False
Decimal native
pip install simplejson
rich.print_json()
Terminal saja
โœ… (input)
Standar
โœ…
โŒ
pip install rich

Pertanyaan yang Sering Diajukan

Bagaimana cara pretty print JSON di Python?

Panggil json.dumps(data, indent=4). Parameter indent menentukan jumlah spasi per level nesting. Import modul json terlebih dahulu โ€” modul ini sudah termasuk dalam library standar Python sehingga tidak perlu pip install. Sertakan ensure_ascii=False jika data Anda mengandung karakter non-ASCII seperti huruf beraksen atau karakter CJK.

python
import json

user = {"username": "budi_s", "plan": "enterprise", "permissions": ["read", "write", "deploy"]}
print(json.dumps(user, indent=4))

Apa perbedaan antara json.dumps() dan json.dump()?

json.dumps() (dengan "s") mengembalikan string terformat di memori. json.dump() (tanpa "s") menulis langsung ke objek file โ€” sertakan file handle yang terbuka sebagai argumen kedua. Untuk menulis JSON terformat ke disk, json.dump(data, f, indent=4) adalah idiom yang umum dan menghindari pembuatan string perantara.

python
# dumps โ†’ string di memori
formatted = json.dumps(data, indent=4)

# dump โ†’ tulis langsung ke file
with open('output.json', 'w', encoding='utf-8') as f:
    json.dump(data, f, indent=4)

Mengapa json.dumps() menampilkan \uXXXX alih-alih karakter asli?

Secara default ensure_ascii=True meng-escape setiap karakter non-ASCII ke urutan \uXXXX. Set ensure_ascii=False untuk mempertahankan karakter Unicode asli. Ini sangat penting untuk nama, alamat, dan konten buatan pengguna dalam skrip non-Latin.

python
data = {"nama": "Sari Dรฉwi", "kota": "Yogyakarta", "catatan": "cafรฉ & rรฉsumรฉ"}

# Default (ensure_ascii=True) โ€” karakter non-ASCII di-escape
json.dumps(data, indent=4)
# {"nama": "Sari D\u00e9wi", "kota": "Yogyakarta", "catatan": "caf\u00e9 & r\u00e9sum\u00e9"}

# Dengan ensure_ascii=False โ€” karakter asli dipertahankan
json.dumps(data, indent=4, ensure_ascii=False)
# {"nama": "Sari Dรฉwi", "kota": "Yogyakarta", "catatan": "cafรฉ & rรฉsumรฉ"}

Bagaimana cara pretty print string JSON (bukan dict)?

Pertama parse string dengan json.loads(), lalu format dengan json.dumps(). Kedua pemanggilan bisa dirantai dalam satu baris untuk inspeksi cepat di terminal.

python
import json

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

Bisakah saya menggunakan pprint untuk memformat JSON di Python?

pprint.pprint() menghasilkan representasi objek Python, bukan JSON valid. Ia menggunakan True/False/None (sintaks Python) alih-alih true/false/null (sintaks JSON). Jangan pernah meneruskan output pprint ke API atau parser JSON โ€” gunakan json.dumps(indent=4) untuk apapun yang harus berupa JSON valid.

python
import pprint, json

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

pprint.pprint(data)     # {'active': True, 'score': None}  โ† bukan JSON
json.dumps(data, indent=4)  # {"active": true, "score": null}  โ† JSON valid

Bagaimana cara mengurutkan kunci JSON secara alfabet di Python?

Tambahkan sort_keys=True ke json.dumps(). Untuk command line, gunakan python -m json.tool --sort-keys data.json. Kunci yang diurutkan membuat diff JSON mudah dibaca dan membantu menemukan nilai yang berubah.

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 memberi Anda kontrol penuh โ€” serializer kustom, streaming, integrasi pipeline. Ketika hanya perlu memeriksa atau berbagi cuplikan terformat, JSON Formatter ToolDeck adalah jalur tercepat: tempel JSON Anda dan dapatkan hasil yang diindentasi dan disorot tanpa pengaturan lingkungan apa pun.

Alat Terkait

Tersedia juga dalam: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 VolkovPeninjau teknis

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.