JSON Formatter Python — Посібник json.dumps()

·Backend Developer·ПеревіреноDmitri Volkov·Опубліковано

Використовуйте безкоштовний JSON Formatter & Beautifier прямо в браузері — без встановлення.

Спробувати JSON Formatter & Beautifier онлайн →

Коли я налагоджую Python API-клієнт, перше, до чого я звертаюся, — це python pretty print json — один виклик json.dumps(data, indent=4) і нечитабельний однорядковий blob миттєво стає зручним для навігації. Вбудований json модуль Python вирішує це завдання повністю в рамках стандартної бібліотеки — без сторонніх встановлень. Якщо потрібен швидкий результат без написання коду, JSON Formatter від ToolDeck зробить це миттєво. Цей посібник охоплює всі практичні методи: json.dumps() з усіма параметрами, pprint, orjson для високопродуктивного форматування, json.tool CLI, і реальні сценарії — форматування API-відповідей і читання з диска — все з кодом, сумісним з Python 3.8+. Також розглядається серіалізація користувацьких типів на кшталт datetime та UUID, потокова обробка файлів гігабайтного розміру за допомогою ijson, і підсвічування синтаксису в терміналі з rich.

Ключові висновки
  • json.dumps(data, indent=4) вбудований у stdlib Python починаючи з 2.6 — встановлення не потрібне.
  • Передавайте ensure_ascii=False щоразу, коли дані містять букви з діакритикою, символи CJK або emoji.
  • Для datetime, UUID і користувацьких класів використовуйте параметр default= або створіть підклас json.JSONEncoder.
  • separators=(',', ':') прибирає всі пробіли — використовуйте для мережевої передачі або вбудовування в URL.
  • orjson працює у 5–10× швидше за stdlib і нативно підтримує datetime та uuid.UUID.
  • pprint.pprint() виводить Python-синтаксис (True/None), а не валідний JSON — ніколи не використовуйте для файлів або API-відповідей.
  • Для JSON-файлів розміром понад 50 МБ використовуйте потокову обробку через ijson замість json.load(), щоб уникнути MemoryError.

Що таке JSON Pretty Printing?

Pretty printing перетворює щільний мінімізований JSON-рядок на зручний для читання формат з послідовними відступами і переносами рядків. Перетворення є суто косметичним: дані ідентичні, змінюється лише представлення. Модуль json Python вирішує це завдання повністю в рамках стандартної бібліотеки — нічого встановлювати не потрібно.

Before · json
After · json
{"id":"usr_9f3a2b","name":"Олексій Коваль","roles":["admin","editor"],"prefs":{"theme":"dark","lang":"uk"}}
{
    "id": "usr_9f3a2b",
    "name": "Олексій Коваль",
    "roles": [
        "admin",
        "editor"
    ],
    "prefs": {
        "theme": "dark",
        "lang": "uk"
    }
}

json.dumps() — стандартний спосіб форматування JSON

json.dumps() входить до стандартної бібліотеки Python починаючи з версії 2.6 — просто import json, жодної установки не потрібно. Серіалізує будь-який JSON-сумісний Python-об'єкт у форматований рядок. Ключовий параметр — indent: встановіть у 4 (або 2), щоб отримати читабельний вивід.

Python 3.8+ — мінімальний приклад
import json

user = {
    "id": "usr_9f3a2b",
    "name": "Олексій Коваль",
    "roles": ["admin", "editor"],
    "prefs": {"theme": "dark", "lang": "uk"}
}

print(json.dumps(user, indent=4, ensure_ascii=False))
# Output:
# {
#     "id": "usr_9f3a2b",
#     "name": "Олексій Коваль",
#     "roles": [
#         "admin",
#         "editor"
#     ],
#     "prefs": {
#         "theme": "dark",
#         "lang": "uk"
#     }
# }

Для продакшн-використання часто потрібні sort_keys=True (стабільний вивід між запусками) та ensure_ascii=False (зберігати не-ASCII символи в читабельному вигляді):

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": "Тетяна Мельник",
        "score": 4892.5,
        "tags": ["python", "backend", "api"]
    }
}

print(json.dumps(api_response, indent=4, sort_keys=True, ensure_ascii=False))
# Output (ключі відсортовані, кирилиця збережена):
# {
#     "data": {
#         "display_name": "Тетяна Мельник",
#         "score": 4892.5,
#         "tags": ["api", "backend", "python"],
#         "user_id": "usr_9f3a2b"
#     },
#     "status": "success",
#     "timestamp": "2024-05-01T10:30:00Z"
# }
Примітка:json.dumps() повертає рядок. Щоб записати форматований JSON напряму у файл, використовуйте json.dump(data, f, indent=4) (без s) — записує у файловий об'єкт і не створює проміжний рядок у пам'яті.

Довідник параметрів json.dumps()

Усі параметри, крім самого об'єкта, є необов'язковими. За замовчуванням створюється компактний ASCII-безпечний JSON — передавайте параметри явно для зручного для читання виводу.

Параметр
Тип
За замовчуванням
Опис
obj
any
Об'єкт Python для серіалізації в рядок формату JSON.
indent
int | str | None
None
Пробілів на рівень відступу. None = компактний один рядок, 0 = лише переноси рядків, 4 = стандарт.
sort_keys
bool
False
Сортувати ключі словника в алфавітному порядку на всіх рівнях вкладеності.
ensure_ascii
bool
True
Екранувати не-ASCII символи в \uXXXX. Передайте False для збереження Unicode-символів як є.
separators
tuple | None
None
Пара (sep_елементів, sep_ключів). Використовуйте (",", ":") для максимально компактного виводу без пробілів.
default
callable | None
None
Викликається для типів, що не серіалізуються за замовчуванням. Кидайте TypeError для відхилення значення.
allow_nan
bool
True
Серіалізувати float("nan") та float("inf") як JS-літерали. Передайте False, щоб кидався ValueError.

Компактний вивід JSON з параметром separators

За замовчуванням json.dumps() розділяє елементи через ", " і ключі від значень через ": ". Параметр separators перевизначає обидва. Передача (',', ':') прибирає всі пробіли для отримання максимально компактного валідного JSON — зручно для мережевої передачі, вбудовування в URL або зберігання JSON у колонці бази даних, де важливий кожен байт.

Python 3.8+
import json

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

# За замовчуванням — пробіли після роздільників (читабельно)
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)

# Компактно + відсортовані ключі для відтворюваних ключів кешу або хешів вмісту
canonical = json.dumps(payload, separators=(',', ':'), sort_keys=True)
print(canonical)
# {"endpoint":"/api/v2/events","filters":{"limit":100,"status":"active"},"sort":"desc"}
Примітка:Коли ви передаєте indent= разом з separators=, аргумент separators керує лише вбудованими роздільниками — переноси рядків і відступи від indent зберігаються. Для компактного однорядкового виводу опустіть indent (або передайте None) і встановіть separators=(',', ':').

Серіалізація користувацьких об'єктів Python за допомогою параметра default

Стандартний модуль json серіалізує словники, списки, рядки, числа, булеві значення та None — але кидаєTypeError для будь-якого іншого типу. Два найчастіших винуватці у продакшн-коді — 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_usd": 142.50,
    "items": ["pro-subscription", "addon-storage"]
}

json.dumps(order)  # raises TypeError

Підхід 1 — параметр default=

Передайте callable-об'єкт у default=. json.dumps() викликає його для будь-якого об'єкта, який не може обробити. Поверніть серіалізоване представлення або кидайте 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 {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_usd": Decimal("142.50"),
    "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_usd": 142.5,
#     "items": ["pro-subscription", "addon-storage"]
# }

Підхід 2 — створення підкласу json.JSONEncoder

Для повторно використовуваної логіки кодування, спільної для кількох модулів, створення підкласу json.JSONEncoder є чистішим, ніж передача функції default всюди. Перевизначте метод default і викликайте super().default(obj) як останній запасний варіант — це зберігає коректну поведінку помилок для непідтримуваних типів.

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)  # raises TypeError for unknown types

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

# Передайте клас енкодера через cls=
print(json.dumps(order, indent=4, cls=AppEncoder))
# Вивід ідентичний підходу з default=
Примітка:Завжди викликайте super().default(obj) (або явно кидайте TypeError) для нерозпізнаних типів. Мовчазне повернення str(obj) для всього зіпсує об'єкти, які мали б викликати помилку — такий баг важко відстежити у продакшні.

Зворотнє декодування — object_hook

Кодування — лише половина історії. Щоб відновити користувацький Python-об'єкт з JSON, передайте функцію object_hook у json.loads() або json.load(). Хук викликається для кожного декодованого JSON-об'єкта (словника) і може повернути будь-яке Python-значення замість нього — забезпечуючи повний цикл кодування ↔ декодування.

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

# Кодування
event = Event("login", datetime(2024, 5, 1, 10, 30), "usr_9f3a2b")
json_str = json.dumps(event, default=encode_event, indent=4)

# Декодування назад в екземпляр 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
Примітка:object_hook викликається для кожного вкладеного словника в документі — не лише для верхнього рівня. Включіть поле-дискримінатор (наприклад, "__type__"), щоб хук міг відрізнити ваші користувацькі об'єкти від звичайних словників, які слід залишити як є.

pprint — альтернативний модуль (і коли його не використовувати)

Модуль Python pprint (pretty printer) форматує структури даних Python для зручного читання в терміналі. Він працює з розібраними Python-об'єктами, а не з JSON-рядками — і його вивід використовує Python-синтаксис, а не 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 — валідний 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-ендпоінт і не записуйте його в .json-файл — це зламає будь-який JSON-парсер, що очікує стандартний синтаксис. Використовуйте json.dumps(indent=4) для будь-якого виводу, який має бути валідним JSON.

Коли pprint доречний: швидкий перегляд Python-об'єктів у REPL або відлагоджувальному логу, особливо коли об'єкт містить типи, що не серіалізуються в JSON (множини, екземпляри користувацьких класів, dataclass-об'єкти до конвертації).

Як форматувати JSON-відповідь з requests

Найпоширеніший реальний сценарій: у вас є JSON-файл на диску або HTTP-відповідь від API, і ви хочете відформатувати її для налагодження або логування. В обох випадках підхід однаковий — розібрати у словник Python, потім відформатувати через json.dumps().

Читання з файлу

Python 3.8+
import json

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

    # Форматований вивід у консоль
    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"Invalid JSON: {e}")
except FileNotFoundError:
    print(f"File not found: config.json")

Форматування API-відповіді

Python 3.8+ (requires: 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 is not JSON:\n{resp.text[:500]}")

pretty_print_api("https://api.github.com/repos/python/cpython")
Примітка:response.json() вже розбирає тіло відповіді — викликати json.loads() окремо не потрібно. Завжди додавайте raise_for_status() перед зверненням до .json(), щоб перехоплювати помилки 4xx/5xx раніше, ніж вони викличуть незрозумілу помилку розбору.

Форматування JSON з командного рядка

Python постачається з json.tool — CLI-модулем для форматування JSON прямо з терміналу, без написання Python-скрипту. Доступний на будь-якій машині з встановленим Python.

bash
# Форматувати локальний файл
python -m json.tool config.json

# Передати API-відповідь через форматтер
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

# Користувацький відступ (Python 3.9+)
python -m json.tool --indent 2 data.json
Примітка:Python 3.9 додав прапорці --indent та --no-indent. Для потужнішої фільтрації JSON у терміналі розгляньте jq — але python -m json.tool покриває завдання форматування без додаткових залежностей.

Якщо ви взагалі не в терміналі — вставляєте відповідь із Postman або лог-файл — JSON Formatter від ToolDeck дозволяє вставити, відформатувати і скопіювати за один крок із вбудованою підсвіткою синтаксису та валідацією.

Альтернативні бібліотеки: orjson та rich

orjson — у 5–10× швидше з нативною підтримкою типів

Стандартного модуля json достатньо для більшості випадків, але якщо ви серіалізуєте тисячі об'єктів на секунду — у пайплайнах логування, високонавантажених API, при великих експортах даних — orjson працює у 5–10× швидше. Він також нативно підтримує типи, які стандартна бібліотека не може серіалізувати без користувацької функції default: datetime, uuid.UUID, масиви numpy та 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, а не рядок — викличте .decode() якщо потрібен рядок. Він підтримує лише 2-пробільний відступ через OPT_INDENT_2; для 4-пробільного виводу використовуйте стандартний json.dumps(indent=4).

rich — підсвічування синтаксису в терміналі

Якщо ви регулярно переглядаєте JSON у терміналі або REPL, rich відображає кольоровий синтаксично підсвічений вивід, що робить глибоко вкладені структури читабельними з першого погляду. Ключі, рядки, числа і булеві значення отримують різні кольори — набагато зручніше для перегляду, ніж монохромний текст. Це інструмент лише для налагодження, а не для продакшн-серіалізації.

bash — встановлення
pip install rich
Python 3.8+
from rich import print_json
import json

# print_json() приймає 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)

# Для форматування Python-словника спочатку конвертуйте в рядок
data = {
    "status": "success",
    "count": 42,
    "tags": ["python", "api", "backend"]
}
print_json(json.dumps(data))
Попередження:rich.print_json() виводить ANSI escape-коди для кольору терміналу — ніколи не захоплюйте цей вивід і не записуйте його в .json-файл і не надсилайте як API-відповідь. Використовуйте json.dumps(indent=4) для будь-якого машиночитаємого виводу.

simplejson — сумісна заміна stdlib

simplejson — бібліотека, що стала стандартним модулем json Python — вона досі підтримується незалежно і випереджає stdlib у ряді функцій. Це справжня заміна без зміни коду: замініть імпорт, і решта коду залишається незмінною. Корисна, коли потрібна підтримка Decimal без користувацького енкодера або при роботі зі старими середовищами Python.

bash — встановлення
pip install simplejson
Python 3.8+
import simplejson as json  # identical API to the stdlib
from decimal import Decimal

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

# simplejson серіалізує Decimal нативно — default= не потрібен
print(json.dumps(order, indent=4, use_decimal=True))
# {
#     "item": "API subscription",
#     "price": 49.99,
#     "quantity": 3
# }
Примітка:Для чистої продуктивності orjson — кращий вибір. Звертайтесь до simplejson, коли потрібна нативна серіалізація Decimal без написання користувацького енкодера, або при роботі з кодовою базою, що вже його використовує.

Обробка великих JSON-файлів без нестачі пам'яті

json.load() читає весь файл у пам'ять, перш ніж ви зможете отримати доступ до одного поля. На файлі з мільйонами записів або payload обсягом понад гігабайт це викликає MemoryError — або в кращому випадку змушує процес іти в swap і сповільнюватися.

Потокова обробка з ijson

ijson — потоковий JSON-парсер, що генерує елементи по одному з файлового об'єкта. Ви ітеруєтесь по елементах масиву, не утримуючи весь датасет у пам'яті — пікове споживання пам'яті пропорційне одному об'єкту, а не розміру файлу.

bash — встановлення
pip install ijson
Python 3.8+
import ijson
from decimal import Decimal

# events.json структура: {"events": [...мільйони об'єктів...]}
total_revenue = Decimal("0")
login_count = 0

with open("events.json", "rb") as f:   # ijson вимагає бінарний режим
    for event in ijson.items(f, "events.item"):
        if event.get("type") == "purchase":
            total_revenue += Decimal(str(event["amount_usd"]))
        elif event.get("type") == "login":
            login_count += 1

print(f"Revenue: ${total_revenue:.2f}  |  Logins: {login_count}")
# Обробляє файл 2 ГБ при ~30 МБ пікового споживання пам'яті
Примітка:Перемикайтесь з json.load() на ijson, коли файл перевищує приблизно 50–100 МБ. Нижче цього порогу json.load() простіший і значно швидший, оскільки використовує внутрішній C-extension парсер. Вище 100 МБ економія пам'яті від потокової обробки переважує додаткові накладні витрати.

NDJSON — один JSON-об'єкт на рядок

NDJSON (Newline Delimited JSON, також відомий як JSON Lines або .jsonl) зберігає один повний JSON-об'єкт на рядок. Експортери логів, Kafka-консьюмери та пайплайни даних часто використовують цей формат, оскільки кожен рядок можна дописувати і читати незалежно — не потрібно розбирати весь файл для додавання запису. Стандартна бібліотека обробляє його без додаткових залежностей.

Python 3.8+
import json
from pathlib import Path

# Запис NDJSON — одна подія на рядок
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']} bought {event['sku']}")

Поширені помилки

Я бачив ці чотири помилки майже в кожному code review, пов'язаному з серіалізацією JSON — особливо у розробників, що прийшли з JavaScript, де JSON.stringify обробляє кодування автоматично.

Використання print(data) замість json.dumps()

Проблема: print() на словнику використовує Python repr — вивід показує True/None (синтаксис Python), а не true/null (синтаксис JSON). Це не валідний 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 з не-ASCII текстом

Проблема: Спеціальні символи (букви з діакритикою, кирилиця, CJK, emoji) екрануються в послідовності \\uXXXX, роблячи вивід нечитабельним.

Рішення: Передайте ensure_ascii=False для збереження вихідних Unicode-символів.

Before · Python
After · Python
user = {"name": "Олексій Коваль"}
json.dumps(user, indent=2)
# {"name": "\u041e\u043b\u0435\u043a\u0441\u0456\u0439 \u041a\u043e\u0432\u0430\u043b\u044c"}
json.dumps(user, indent=2, ensure_ascii=False)
# {"name": "Олексій Коваль"}
Використання json.dumps() для запису у файл

Проблема: json.dumps() повертає рядок; після цього потрібен окремий виклик f.write(), що створює зайвий проміжний рядок.

Рішення: Використовуйте json.dump(data, f, indent=4) — записує напряму у файловий об'єкт.

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-синтаксис (True, None, одинарні лапки), який JSON-парсери відкидають.

Рішення: Використовуйте json.dumps(indent=4) для будь-якого виводу, який має розбиратися як 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% випадків без залежностей. Звертайтесь до orjson при серіалізації на гарячому шляху або коли об'єкти включають поля datetime і UUID. Використовуйте simplejson коли потрібна сумісність зі stdlib і нативна підтримка Decimal з коробки. Залиште rich.print_json() і pprint виключно для локального перегляду в терміналі — жоден з них не дає машиночитабельний вивід.

Метод
Вивід
Валідний JSON
Швидкість
Non-ASCII
Власні типи
Встановлення
json.dumps(indent=4)
String
Стандарт
ensure_ascii=False
default= / JSONEncoder
Вбудовано
json.dump(f, indent=4)
Файл
Стандарт
ensure_ascii=False
default= / JSONEncoder
Вбудовано
pprint.pprint()
Python repr
Стандарт
Нативно
✅ (будь-який repr)
Вбудовано
orjson.dumps(OPT_INDENT_2)
Bytes
у 5–10× швидше
Нативно
datetime, UUID, numpy
pip install orjson
python -m json.tool
CLI stdout
Стандарт
Вбудовано
simplejson.dumps()
String
~1.5× швидше
ensure_ascii=False
Decimal нативно
pip install simplejson
rich.print_json()
Лише термінал
✅ (вхід)
Стандарт
pip install rich

Часті запитання

Як відформатувати JSON у Python з відступами?

Викличте json.dumps(data, indent=4). Параметр indent задає кількість пробілів на кожен рівень вкладеності. Спочатку імпортуйте модуль json — він входить до стандартної бібліотеки Python, жодної установки через pip не потрібно. Передайте ensure_ascii=False, якщо дані містять не-ASCII символи: букви з діакритикою, кирилицю, символи CJK.

python
import json

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

У чому різниця між json.dumps() та json.dump()?

json.dumps() (з буквою "s") повертає відформатований рядок у пам'яті. json.dump() (без "s") записує безпосередньо у файлоподібний об'єкт — передайте відкритий файловий дескриптор другим аргументом. Для запису форматованого JSON на диск json.dump(data, f, indent=4) є ідіоматичним підходом і не створює проміжний рядок у пам'яті.

python
# dumps → рядок у пам'яті
formatted = json.dumps(data, indent=4)

# dump → запис напряму у файл
with open('output.json', 'w', encoding='utf-8') as f:
    json.dump(data, f, indent=4)

Чому json.dumps() показує \u0441\u0442\u0440 замість реальних символів?

За замовчуванням ensure_ascii=True екранує кожен не-ASCII символ у послідовність \uXXXX. Передайте ensure_ascii=False, щоб зберегти вихідні Unicode-символи. Особливо важливо при роботі з іменами, адресами та будь-яким користувацьким контентом нелатинськими алфавітами.

python
data = {"city": "Київ", "greeting": "你好"}

# За замовчуванням — екрановано
json.dumps(data, indent=4)
# {"city": "\u041a\u0438\u0457\u0432", ...}

# Читабельно
json.dumps(data, indent=4, ensure_ascii=False)
# {"city": "Київ", "greeting": "你好"}

Як відформатувати JSON-рядок (не словник)?

Спочатку розберіть рядок за допомогою json.loads(), потім відформатуйте через json.dumps(). Обидва виклики можна об'єднати в один рядок для швидкого перегляду в терміналі.

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-представлення об'єкта, а не валідний JSON. Він використовує True/False/None (синтаксис Python), а не true/false/null (синтаксис JSON). Ніколи не передавайте вивід pprint в API або JSON-парсер — використовуйте 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(). Для командного рядка використовуйте python -m json.tool --sort-keys data.json. Відсортовані ключі роблять JSON-дифи читабельними і допомагають одразу помічати змінені значення.

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 дає повний контроль — кастомні серіалізатори, стримінг, інтеграція в пайплайни. Коли потрібно просто перевірити або поділитися відформатованим фрагментом, 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.