- JSON чітко відображає основні типи Python, а об'єкти та масиви представлені як словарі та списки, що спрощує обмін даними.
- Модуль json у Python надає гнучкі функції виведення/завантаження даних з опціями гарного друку, користувацькими кодувальниками та стабільним упорядкуванням ключів.
- Читання, запис та парсинг вкладених JSON з файлів та API спираються на ті самі основні інструменти, поєднані з ретельною обробкою помилок.
- Окрім базової серіалізації, JSON у Python підтримує форматування, валідацію та інтеграцію з іншими форматами даних, такими як CSV та XML.

JSON непомітно став мовою за замовчуванням для даних в Інтернеті, і якщо ви пишете на Python, ви стикаєтеся з ним скрізь: API, файли конфігурації, невеликі «бази даних» для сторонніх проектів, журнали та навіть тестові фікстури. Розуміння того, як типи даних Python відображаються на JSON та як json Модуль, який дійсно працює, – це одна з тих навичок, яка раптово спрощує багато повсякденних завдань.
Цей посібник розглядає JSON з точки зору програміста на Python, пояснення того, що таке JSON, як він пов'язаний з JavaScript, які типи Python він може представляти, а також як розбирати, генерувати, гарно друкувати, перевіряти та налаштовувати JSON за допомогою jsonМи також розглянемо реальні випадки використання, такі як робота з файлами та API, а також хитрощі для обробки вкладених даних та граничних випадків, таких як помилки або спеціальні значення, такі як NaN і нескінченності.
Що таке JSON і як він пов'язаний з даними Python
JSON, скорочення від JavaScript Object Notation (нотація об'єктів JavaScript), — це текстовий формат для структурованих даних. який спочатку запозичив свій синтаксис з об'єктів та масивів JavaScript. Незважаючи на коріння JavaScript, JSON не залежить від мови та підтримується практично кожною сучасною мовою програмування, включаючи Python, що робить його ідеальним для обміну даними між сервісами, клієнтами та серверами.
Концептуально, JSON використовує лише два складові структурні блоки: JavaScript об'єкт і JavaScript масивОб'єкт поводиться дуже схоже на словник Python, а масив — як список Python. За допомогою цих двох елементів, а також невеликого набору примітивних типів, JSON може описувати складні вкладені структури даних.
Об'єкт у JavaScript (і JSON) виглядає так: {"key1": value1, "key2": value2}Це колекція пар ключ-значення, де ключі є рядками, а значеннями можуть бути будь-які дійсні значення JSON (включаючи інші об'єкти або масиви). Це дуже відповідає Python. dict.
Масив у JavaScript (і JSON) схожий на список у Python: Це впорядкована колекція значень, знову ж таки з використанням будь-якого допустимого типу JSON. Разом об'єкти та масиви можуть бути довільно вкладені для моделювання багатих даних, таких як профілі користувачів, дерева конфігурації або відповіді API.
Зіставлення між типами JSON та типами Python дуже просте, саме тому іноді можна почути, як люди жартома називають це «PYON» (нотація об'єктів Python). Коли Python кодує або декодує JSON, застосовуються такі відповідності:
- JSON-об'єкт → Python
dict - JSON-масив → Python
list - Рядок JSON → Python
str - Номер JSON (ціле число) → Python
int - Номер JSON (реальний) → Python
float - JSON
true→ PythonTrue - JSON
false→ PythonFalse - JSON
null→ PythonNone
Одним важливим обмеженням є те, що ключі об'єктів JSON завжди є рядками, тож якщо ви кодуєте Python dict з нерядковими ключами (наприклад, цілими числами або кортежами) ці ключі будуть перетворені на рядки або викликатимуть помилки залежно від ваших налаштувань. JSON чудово підходить для зберігання структурованих даних, таких як конфігурації або записи, але він... НЕ загальний механізм маринування для довільних об'єктів Python.

Вбудований JSON-модуль Python
Python постачається зі стандартним бібліотечним модулем під назвою json, що надає вам усе необхідне для роботи з JSON: розбір рядків, завантаження з файлів, серіалізацію об'єктів Python та налаштування кодування та декодування даних. Вам не потрібна жодна зовнішня залежність для типових завдань JSON.
Чотири основні функції, які ви використовуватимете більшу частину часу: json.dumps() та json.dump() для перетворення об'єктів Python у JSON та json.loads() та json.load() для переходу від JSON назад до типів Python. Версії «s» працюють з рядками, тоді як версії без «s» працюють з файлоподібними об'єктами.
Команда json кодер за замовчуванням підтримує певний набір типів Python, а саме dict, list, tuple (як масиви), str, числа (int, float, та перерахування, похідні від цілочисельних/чисел з плаваючою комою), а також три спеціальні одиночні елементи True, False та NoneВони конвертуються в їхні JSON-еквіваленти відповідно до зіставлення, описаного раніше.
Якщо вам потрібно серіалізувати власні об'єкти або типи даних, дизайн модуля є розширюваним: ви можете створити підклас JSON-енкодера та реалізувати default() метод або передати користувацький default функціонувати в json.dump() / json.dumps()Цей користувацький гачок має повертати щось, що можна серіалізувати у форматі JSON (наприклад, dict or list), або підвищити TypeError якщо воно не знає, як обробляти заданий об'єкт.
Під капотом модуль також пропонує такі методи, як encode() та iterencode(), які конвертують дані Python у рядки JSON, з iterencode() поступове отримання закодованих фрагментів. Вони рідше використовуються безпосередньо, але про них варто знати, якщо вам потрібно передавати дуже великі JSON-відповіді.
Конвертація об'єктів Python у JSON
Коли ви хочете перетворити дані Python на текст JSON, ви використовуєте json.dump() or json.dumps(), залежно від того, чи потрібно записувати безпосередньо у файл, чи отримувати рядок JSON у пам'яті. Обидві функції мають однакові основні параметри, які дозволяють вам контролювати поведінку перетворення.
Функція json.dump(obj, fp, ...) приймає об'єкт Python та файлоподібний об'єкт, та записує JSON-представлення obj до цього файлу. Його аналог у пам'яті, json.dumps(obj, ...), повертає рядок JSON замість запису у файл. Вони обидва приймають низку ключових аргументів, таких як skipkeys, ensure_ascii, check_circular, allow_nan, indent, separators, default та sort_keys.
Кожен із цих параметрів змінює поведінку кодування таким чином, що це має велике значення в реальних проектах: Ви можете вибрати, чи пропускати недійсні ключі, примусово виводити ASCII, гарно друкувати результат, контролювати пробіли, визначати власну серіалізацію для нестандартних об'єктів або стабілізувати порядок ключів для тестування та порівняння.
Ось що означають основні параметри на практиці:
skipkeys: якщо встановленоTrue, ключі словника, які не належать до типуstr,int,float,boolorNoneмовчки пропускаються замість того, щоб викликатиTypeErrorЯкщо ви надаєте перевагу швидкому реагуванню на незвичайні ключі, залиште це якFalse.ensure_ascii: колиTrue(за замовчуванням), символи, що не належать до ASCII, та недруковані символи екрануються (наприклад, як\uXXXX), тому вихід залишається чистим ASCII. КолиFalseСимволи Unicode записуються як є, що зазвичай краще для зручних для людини конфігурацій або журналів.check_circular: ifTrue, кодувальник перевіряє циклічні посилання у списках, словниках та користувацьких закодованих об'єктах, щоб запобігти нескінченній рекурсії. Встановивши його наFalseвимикає цю систему безпеки та може призвести доRecursionErrorякщо ваші структури є самопосилальними.allow_nan: ifTrue, спеціальні значення з плаваючою комою, такі якNaN,Infinityта-Infinityдозволені та закодовані у JavaScript-сумісному вигляді, навіть якщо вони не є суворо валідним JSON згідно зі специфікацією. ЯкщоFalse, спроба кодувати такі значення призведе доValueError.indent: невід’ємне ціле число (або рядок), яке керує гарним друком. Додатне число означає, що кількість пробілів на кожному вкладеному рівні. Рядок (наприклад"\t") використовується безпосередньо для відступів.None(за замовчуванням) вибирає найкомпактніше представлення, без додаткових символів нового рядка, окрім необхідних.separators: кортеж(item_separator, key_separator)керування пунктуацією та пробілами між елементами, а також між ключами та значеннями. Для найщільнішого JSON зазвичай використовується(",", ":")щоб видалити всі додаткові пробіли.default: функція, яка отримує будь-який об'єкт, який кодер не знає, як обробити. Вона повинна повернути JSON-серіалізований замінник (наприклад,dictorlist), або підвищитиTypeErrorЦе головний гачок для створення серіалізованих власних класів.sort_keys: ifTrue, словники кодуються з відсортованими ключами. Це надзвичайно зручно для регресійних тестів та відтворюваних виводів, де потрібно, щоб дампи JSON були стабільними протягом усіх запусків.
Як конкретний приклад, уявіть, що у вас є змішаний список Python що містить цілі числа та словник з назвою, ідентифікатором та числом з плаваючою комою. Ви можете створити та зберегти JSON ось так:
import pathlib
import json
path = pathlib.Path("myTextFile.json")
data =
with path.open(mode="wt") as f:
json.dump(data, f)
print(json.dumps(data, indent=4))
Друкований JSON буде добре відформатований завдяки indent=4, відображення кожного елемента списку та ключа словника в окремому рядку. Це значно спрощує налагодження та ручне редагування порівняно з одним щільним рядком тексту.
Розбір JSON назад у Python
Щоб повернутися від тексту JSON до об'єктів Python, ви використовуєте відповідну пару функцій: json.load() (для файлоподібних об'єктів) та json.loads() (для рядків JSON). Ці функції аналізують вхідні дані та відтворюють типи Python відповідно до тієї ж таблиці зіставлення, що й раніше.
Підписи виглядають приблизно так: json.load(fp, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, kw) та json.loads(s, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, kw)На базовому рівні ви можете викликати їх, використовуючи лише вхідні дані JSON, але додаткові аргументи відкривають шлях до більш просунутої поведінки парсингу.
Гачки, як object_hook та object_pairs_hook дозволяють налаштувати перетворення об'єктів JSON на структури Python, надаючи вам або декодований dict або список (key, value) пари відповідно. Це корисно, якщо ви хочете створювати власні класи безпосередньо з JSON або зберігати певний порядок.
Інші викликані функції, такі як parse_float, parse_int та parse_constant дозволяють контролювати інтерпретацію чисел та спеціальних токенів. Наприклад, ви можете використовувати Decimal замість float для грошових значень або перетворення "NaN", "inf" та "-inf" на сторожові об'єкти на ваш вибір.
Продовжуючи попередній приклад, ви можете прочитати написаний вами JSON-файл ось так:
with path.open(mode="rt") as f:
data = json.load(f)
print(data)
Результуючим результатом буде звичайний список та словник Python, наприклад , якими можна маніпулювати за допомогою всіх звичайних операцій Python. З точки зору вашого коду, це знову ж таки «просто дані».
Які типи Python може конвертувати в JSON
Не кожен об'єкт Python можна одразу перетворити на JSON, тому корисно пам'ятати дозволений набір. Практичні енкодери підтримують поширені контейнерні та скалярні типи, а також логічні значення та None, та зіставити їх з мінімальним набором типів JSON.
За замовчуванням ви можете безпечно передавати наступні об'єкти Python у json.dumps():
dict(закодовано як об'єкти JSON)listтаtuple(закодовано як масиви JSON)str(закодовано як рядки JSON)intтаfloat(закодовано як числа JSON)TrueтаFalse(закодовано якtrueтаfalse)None(закодовано якnull)
Коли Python кодує їх, зіставлення з JSON є простим, і навпаки під час декодування. Наприклад, Python tuple стає масивом JSON, і ви отримуєте list знову при завантаженні. Перерахування, похідні від int or float також можуть бути закодовані як числа.
Все інше потребує налаштування default обробник (щоб перетворити об'єкти на серіалізуване представлення) або спричинить TypeErrorЦе задумано задумом: JSON призначений для даних, а не для довільних графів об'єктів з поведінкою та методами, як ви могли б серіалізувати за допомогою pickle.
Для більшості повсякденної роботи ця підмножина типів охоплює більшість випадків використання, включаючи корисні навантаження API, дерева конфігурації, налаштування користувача, базові журнали та невеликі файли, схожі на бази даних, для прототипів або інструментів для одного користувача.
Гарний друк, компактний вивід та впорядковані клавіші
Вивід у форматі необробленого JSON, як правило, повністю коректний, але його важко читати. оскільки він часто генерується без зайвих пробілів. Для налагодження, ведення журналу або обміну з іншими розробниками часто потрібен читабельний JSON з відступами, а не однорядковий.
Команда indent параметр json.dumps() є головним важелем для гарного друку, що дозволяє вам вказати Python, скільки пробілів (або який рядок) використовувати для кожного рівня відступу. Типовий вибір — indent=4, хоча деякі кодові бази надають перевагу двом пробілам або символам табуляції; стилістичні домовленості різняться між проектами.
Команда separators аргумент дозволяє ще більше налаштувати пробіли, надаючи кортеж типу (", ", ": ") за замовчуванням для зручного для людини виводу. Якщо вам потрібне максимально компактне представлення, наприклад, щоб скоротити розмір корисного навантаження в мережі, ви можете встановити separators=(",", ":") щоб видалити пробіли після ком і двокрапок.
Коли вас цікавить детермінований вихід, наприклад, у модульних тестах або порівняннях знімків, активує sort_keys=True створює відсортований порядок виведення ключів словника кодера. Таким чином, два запуску, які створюють семантично ідентичні дані, не відрізняються лише тому, що словники випадково виводять ключі в різній послідовності.
Разом indent, separators та sort_keys дати вам багато контролю щодо того, чи ваш JSON оптимізований для машин (компактний, без пробілів) чи для людей (з відступами, вирівняний, зі стабільною формою в різних прогонах).
Вкладені дані, стратегії парсингу та шаблони доступу
У реальному JSON плоскі структури є винятком; Зазвичай ви маєте справу з вкладеними об’єктами та масивами. Уявіть собі типовий запис користувача в застосунку електронної комерції: особиста інформація, вкладені адреси доставки, вкладені платіжні дані та, можливо, список замовлень, кожне з яких є складною структурою саме по собі.
Під час декодування JSON у Python вкладені дані стають комбінаціями словників та списків, і ви можете отримати до нього доступ за допомогою стандартного пошуку за індексом та ключем. Для поверхневих структур це просто: data, data, І так далі.
Для глибоко вкладених або динамічних структур ви можете віддати перевагу більш загальному підходу, наприклад, написання невеликої рекурсивної функції, яка шукає ключі або обходить дерево словників та списків. Рекурсивні рішення часто коротші та легші для читання, ніж ітераційні, під час обходу довільно вкладених даних.
До невкладеного (плоского) JSON легше отримати безпосередній доступ за допомогою жорстко закодованих ключів, що може бути цілком прийнятним для невеликих утиліт або коли ви повністю контролюєте вхідні дані. Однак, під час використання зовнішніх API зазвичай пишуть невеликі допоміжні функції, які інкапсулюють структуру, щоб не розкидати її. ланцюжки по всій вашій кодовій базі.
Незалежно від глибини, одне й те саме json.loads() застосовується поведінка: Функція приймає рядок JSON та створює нативні типи Python, якими потім можна маніпулювати за допомогою звичайних інструментів Python. Немає потреби у спеціальному синтаксисі, окрім звичайного. dict та list індексація.
Робота з JSON-файлами: читання, запис та додавання
JSON створює напрочуд зручний і легкий формат зберігання даних для невеликих проектів, файлів конфігурації або скриптів, яким потрібно зберігати певний постійний стан. Замість того, щоб одразу звертатися до повної бази даних, часто можна обійтися одним або двома JSON-файлами на досить тривалий час.
Запис JSON у файл зазвичай складається з двох кроків: серіалізувати дані Python за допомогою json.dumps() або безпосередньо з json.dump(), а потім переконайтеся, що результуючий рядок записаний на диск. Якщо ви викликаєте open('data.json', 'w'), ви отримуєте дескриптор файлу в режимі запису, який або створює файл, або обрізає його, якщо він вже існує.
Для вкладених структур протокол нічим не відрізняється від плоских даних: ти все ще користуєшся тим самим json.dump() виклик, а вкладені комбінації списків та словників кодуються рекурсивно. Єдине рішення, яке вам зазвичай потрібно прийняти, це те, який відступ ви хочете для зручності читання в порівнянні з розміром файлу.
Читання JSON з файлу відбувається навпаки: відкриття файлу в текстовому режимі, передати файловий об'єкт до json.load(), і ви отримуєте назад свою структуру даних Python. Знову ж таки, поведінка не залежить від того, наскільки глибоко вкладено — декодер обробляє все це за вас.
Якщо вам потрібно додати дані JSON до існуючих файлів, Речі стають більш тонкими. Сам JSON не підтримує «потокове додавання» тривіальним чином, оскільки весь файл має бути валідним JSON. Поширеною схемою є зберігання масиву записів та читання/зміна/запис усього масиву або використання JSON з роздільниками, де кожен рядок є окремим об'єктом JSON, до якого можна додавати дані, не перезаписуючи попередні рядки.
JSON у реальному світі: API, сховище та обмін
Як тільки ви починаєте створювати реальні застосунки, JSON швидко стає з'єднувальною ланкою який з'єднує веб-клієнти та сервери, мікросервіси та сторонні API. Він цінується як через свою компактність, так і через те, що люди все ще можуть досить легко його читати та редагувати.
У взаємодії з API JSON є найпоширенішим форматом корисного навантаження, особливо в RESTful-сервісах. Програми Python зазвичай використовують такі бібліотеки, як requests надсилати HTTP-запити та отримувати JSON-відповіді, а потім проаналізуйте ці відповіді за допомогою json.loads() або за допомогою допоміжних методів, які його обгортають.
JSON також є популярним форматом для файлів конфігурації та журналів, де його структурована природа ключ-значення робить його набагато виразнішим, ніж звичайний текст, залишаючись при цьому простим порівняно з повними базами даних. Системні компоненти можуть обмінюватися конфігурацією через JSON, а агрегатори журналів можуть аналізувати журнали JSON для їх легшої фільтрації або аналізу.
Ще один великий випадок використання — серіалізація та десеріалізація структур даних, перетворення колекцій у пам'яті на рядки JSON (серіалізація) та їх подальше відновлення (десериалізація). Таким чином зберігаються налаштування користувача, передавати структуровані повідомлення через черги або надсилати вкладені об'єкти через межі сервісу, за умови, що ви дотримуєтеся JSON-сумісних типів або надаєте власні кодувальники.
Окрім лише JSON, код Python часто потребує конвертації між JSON та іншими форматами, такі як XML, CSV або звичайний текст. Наприклад, ви можете прочитати CSV зі застарілої системи, перетворити його на список словників, а потім вивести його як JSON для сучасного API. Або ви можете отримати JSON з API, нормалізувати його та записати CSV для аналітиків, щоб вони завантажували його в електронні таблиці.
Форматування, перевірка та додаткові операції над JSON
Як тільки ви освоїте базові навички читання та письма, Існує низка невеликих, але корисних операцій, які ви можете виконувати з даними JSON для покращення свого робочого процесу: форматування для зручності читання, вирівнювання вкладених структур, перевірка того, що рядок дійсно є JSON, та сортування даних для узгодженого порівняння.
Гарний друк з json.dumps(..., indent=...) це перший крок, що забезпечує зручно розташовані ієрархії, що полегшують виявлення структурних проблем з першого погляду. Це особливо корисно під час налагодження або при обміні прикладами в документації.
Зведення вкладених JSON-файлів до меншин може спростити подальшу обробку та аналіз, особливо якщо вам потрібно конвертувати дані в табличну форму, таку як CSV, або передати їх інструментам, які очікують пари ключ-значення, а не глибоко вкладені об'єкти. Зазвичай ви реалізуєте вирівнювання самостійно за допомогою рекурсії або ітеративного обходу словників та списків.
Перевірка JSON часто зводиться до спроб його розбору та перехоплення винятків, особливо якщо ви просто перевіряєте синтаксичну правильність рядка. Для більш ретельних перевірок можна використовувати JSON Schema та зовнішні бібліотеки, але в багатьох випадках простий try/except навколо json.loads() достатньо.
Сортування даних JSON за певними значеннями або ключами може допомогти під час порівняння відповідей, створення стабільних знімків для тестів або просто забезпечення групування подібних об'єктів. Ви можете або сортувати базові списки та словники Python перед дампом, або покладатися на sort_keys=True коли основна увага приділяється впорядкуванню ключів в об'єктах.
Обробка помилок під час роботи з JSON
Навіть добре структуровані системи можуть зіткнутися з неправильно сформованим JSON або неочікуваними даними, тому надійна обробка помилок під час розбору та кодування JSON є критично важливою. Python виражає ці проблеми за допомогою винятків, і ідіоматичний спосіб їх вирішення — це обгортання операцій в try...except блоки
Під час декодування JSON найпоширенішою проблемою є недійсний синтаксис, наприклад, пропущені лапки навколо назв властивостей або завершальні коми. json модуль викличе помилку декодування (зазвичай json.JSONDecodeError), які ви можете перехоплювати та реєструвати або перетворювати на зручні для користувача повідомлення.
Наприклад, спроба розібрати пошкоджений рядок може призвести до помилки, як-от: Failed to decode JSON: Expecting property name enclosed in double quotes: line 1 column 29 (char 28)Таке повідомлення повідомляє не лише про невдачу парсингу, але й про те, де у вхідних даних стався переплутаний синтаксичний аналізатор.
З боку кодування ви можете натрапити на TypeError під час спроби серіалізації непідтримуваних типів, or ValueError якщо ви забороните NaN і нескінченності через allow_nan=False але ваші дані містять такі значення. Циклічні посилання в контейнерах також можуть спрацьовувати RecursionError якщо вимкнути циклічні перевірки.
Найкраща практика — розглядати JSON-операції як помилкові операції вводу-виводу, особливо під час читання з мережевих джерел або зовнішніх файлів: завжди припускайте, що щось може піти не так, і відповідно перехоплюйте винятки, можливо, додаючи шари перевірки, щоб застосувати більш конкретні обмеження до ваших даних. Обгортання json.loads() або допоміжні методи API в try...except блоки захищають решту вашого коду від каскадних збоїв і дозволяють повертати зручні помилки JSON клієнтам, коли це доречно.
Використання JSON з веб-API в Python
Більшість веб-API, з якими ви взаємодієте з Python, надсилатимуть та отримуватимуть JSON, а типовий стек розробки поєднує в собі requests бібліотека (для HTTP) з json модуль (для парсингу та генерації JSON). Таке поєднання робить інтеграцію API дуже природною.
Поширеною схемою є виклик кінцевої точки API, перевірте, чи код стану відповіді вказує на успіх, а потім розібрати тіло JSONЗвідти ви можете отримувати доступ до полів, обробляти вкладені дані та відображати відповідь у власних моделях предметної області або переглядати об'єкти.
Обробка помилок стає особливо важливою, коли задіяні мережеві виклики. оскільки ви можете зіткнутися не лише з недійсним JSON, але й із тайм-аутами, помилками підключення або збоями на стороні сервера, які відповідають HTML замість JSON. json.loads() або допоміжні методи API в try...except блоки захищають решту вашого коду від каскадних збоїв.
Після розбору API JSON поводиться так само, як і будь-яка інша структура даних Python, тому всі методи, обговорені раніше — гарний друк, вирівнювання, валідація, сортування — застосовуються безпосередньо. Зручне перемикання між даними Python та JSON є величезним підвищенням продуктивності під час об'єднання сервісів. Якщо ви зосереджені на створення реальних додатківЗвернення уваги на шаблони обробки JSON на ранній стадії заощадить час налагодження пізніше.
JSON у Python — це не стільки виклик однієї функції, скільки набір інструментів: чіткі зіставлення типів, гнучкі параметри кодування, перехоплювачі для користувацьких типів, простий, але потужний файловий ввід/вивід, а також надійні шаблони для парсингу, форматування та перевірки даних із зовнішнього світу – все це робить JSON природним вибором для програмістів на Python, які працюють із сучасними програмами, керованими даними.