Читання та запис JSON у файл на Python

Вступ

У цьому посібнику ми розглянемо, як читати й писати дані JSON із файлу та до нього на Python за допомогою json модуль

JSON (нотація об'єктів JavaScript) є надзвичайно популярним форматом для серіалізації даних, враховуючи його загальну застосовність і легкість, а також досить зручний для людей. Зокрема, він широко використовується у світі веб-розробки, де ви, ймовірно, зіткнетеся з серіалізованими об’єктами JSON, які надсилаються з REST API, налаштування додатків або навіть просте зберігання даних.

Враховуючи його поширеність, читання та розбір файлів JSON (або рядків) є досить поширеним явищем, і запис JSON для надсилання є таким же поширеним. У цьому посібнику ми розглянемо, як використовувати json модуль для читання та запису JSON у Python.

Запис JSON у файл за допомогою Python за допомогою json.dump() і json.dumps()

Щоб записати вміст JSON у файл на Python – ми можемо використовувати json.dump() та json.dumps(). Це такі окремі методи і досягти іншого результату:

  • json.dumps() – Серіалізує об’єкт у форматі JSON рядок
  • json.dump() – Серіалізовано об’єкт у потік JSON для збереження у файли або сокети

Примітка: Буква «s» у слові «звалища» насправді є скороченням "рядок дампу".

Природний формат JSON подібний до a карта з інформатики – карта key-value пари. У Python a словник є реалізацією карти, тому ми, природно, зможемо точно представити JSON через a dict. Словник може містити інші вкладені словники, масиви, логічні значення або інші примітивні типи, такі як цілі чи рядки.

:::

Примітка: Вбудований json пакет пропонує кілька зручних методів, які дозволяють нам конвертувати між JSON і словниками.

:::

З огляду на це, давайте імпортуємо json модуль, визначте словник з деякими даними, а потім конвертуйте його в JSON перед збереженням у файл:

import json

data = {
    'employees' : [
        {
            'name' : 'John Doe',
            'department' : 'Marketing',
            'place' : 'Remote'
        },
        {
            'name' : 'Jane Doe',
            'department' : 'Software Engineering',
            'place' : 'Remote'
        },
        {
            'name' : 'Don Joe',
            'department' : 'Software Engineering',
            'place' : 'Office'
        }
    ]
}


json_string = json.dumps(data)
print(json_string)

Це призводить до:

{'employees': [{'name': 'John Doe', 'department': 'Marketing', 'place': 'Remote'}, {'name': 'Jane Doe', 'department': 'Software Engineering', 'place': 'Remote'}, {'name': 'Don Joe', 'department': 'Software Engineering', 'place': 'Office'}]}

Тут у нас є простий словник із кількома employees, кожна з яких має a name, department та place, dumps() функції json Модулі звалищах словник у вміст JSON і повертає a JSON рядок.

Після серіалізації ви можете вирішити надіслати його до іншої служби, яка десеріалізує його або, скажімо, збереже. Щоб зберегти цей рядок JSON у файлі, ми просто відкриємо файл у режимі запису та запишемо його. Якщо ви не бажаєте видобувати дані в незалежну змінну для подальшого використання, а хочете просто вивести їх у файл, ви можете пропустити dumps() функції та використання dump() instad:


with open('json_data.json', 'w') as outfile:
    outfile.write(json_string)


with open('json_data.json', 'w') as outfile:
    json.dump(json_string, outfile)

Будь-який файлоподібний об’єкт можна передати другому аргументу dump() навіть якщо це не справжній файл. Гарним прикладом цього може бути сокет, який можна відкривати, закривати та записувати в нього, як у файл.

Читання JSON з файлу за допомогою Python за допомогою json.load() і json.loads()

Зіставлення між вмістом словника та рядком JSON є простим, тому легко конвертувати між ними. Така ж логіка, як і с dump() та dumps() застосовується до load() та loads(). Так само як json.dumps(), json.loads() функція приймає рядок JSON і перетворює його на словник, тоді як json.load() дозволяє завантажити у файл:

import json

with open('json_data.json') as json_file:
    data = json.load(json_file)
    print(data)

Це призводить до:

{'employees': [{'name': 'John Doe', 'department': 'Marketing', 'place': 'Remote'}, {'name': 'Jane Doe', 'department': 'Software Engineering', 'place': 'Remote'}, {'name': 'Don Joe', 'department': 'Software Engineering', 'place': 'Office'}]}

Крім того, давайте прочитаємо рядок JSON у словник:

import json

python_dictionary = json.loads(json_string)
print(python_dictionary)

Що також призводить до:

{'employees': [{'name': 'John Doe', 'department': 'Marketing', 'place': 'Remote'}, {'name': 'Jane Doe', 'department': 'Software Engineering', 'place': 'Remote'}, {'name': 'Don Joe', 'department': 'Software Engineering', 'place': 'Office'}]}

Це особливо корисно для аналізу відповідей REST API, які надсилають JSON. Ці дані надходять до вас у вигляді рядка, який потім можна передати json.loads() безпосередньо, і ви матимете набагато більш керований словник для роботи!

Сортування, красивий друк, роздільники та кодування

Під час серіалізації ваших даних у JSON за допомогою Python стандартний формат, спрямований на мінімізацію необхідної пам’яті для передачі повідомлень, не дуже читабельний, оскільки пробіли видаляються. Хоча це ідеальна поведінка для передачі даних (комп’ютерам не важлива читабельність, а важливий розмір) – іноді вам може знадобитися внести невеликі зміни, наприклад додати пробіли, щоб зробити їх читабельними людиною.

Ознайомтеся з нашим практичним практичним посібником із вивчення Git з передовими методами, прийнятими в галузі стандартами та включеною шпаргалкою. Припиніть гуглити команди Git і фактично вчитися це!

Примітка: json.dump()/json.dumps() та json.load()/json.loads() усі надають кілька варіантів форматування.

Красивий друк JSON у Python

Зробити JSON читабельним для людини (він же «гарний друк») так само просто, як передати ціле значення для indent параметр:

import json
data = {'people':[{'name': 'Scott', 'website': 'stackabuse.com', 'from': 'Nebraska'}]}
print(json.dumps(data, indent=4))

У кожному новому логічному блоці створюється 4-пробілний відступ:

{
    "people": [
        {
            "website": "stackabuse.com", 
            "from": "Nebraska", 
            "name": "Scott"
        }
    ]
}

Іншим варіантом є використання інструмента командного рядка – json.tool. З його допомогою ви можете красиво надрукувати JSON у командному рядку, не впливаючи на переданий рядок, а лише впливаючи на те, як він відображається в стандартному вихідному каналі:

$ echo '{"people":[{"name":"Scott", "website":"stackabuse.com", "from":"Nebraska"}]}' | python -m json.tool
{
    "people": [
        {
            "name": "Scott",
            "website": "stackabuse.com"
            "from": "Nebraska",
        }
    ]
}

Сортування об’єктів JSON за ключами

У термінах JSON:

«Об’єкт — це невпорядкований набір пар ім’я/значення».

Порядок ключів не гарантується, але можливо, вам знадобиться примусово застосувати порядок ключів. Щоб досягти порядку, ви можете пройти True до sort_keys варіант при використанні json.dump() or json.dumps():

import json
data = {'people':[{'name': 'Scott', 'website': 'stackabuse.com', 'from': 'Nebraska'}]}
print(json.dumps(data, sort_keys=True, indent=4))

Це призводить до:

{
    "people": [
        {
            "from": "Nebraska",
            "name": "Scott",
            "website": "stackabuse.com"
        }
    ]
}

Текст і кодування ASCII

За замовчуванням json.dump() та json.dumps() гарантує, що текст у даному словнику Python кодується ASCII. Якщо присутні символи, відмінні від ASCII, вони автоматично екрануються, як показано в наступному прикладі:

import json
data = {'item': 'Beer', 'cost':'£4.00'}
jstr = json.dumps(data, indent=4)
print(jstr)
{
    "item": "Beer",
    "cost": "u00a34.00"
}

Це не завжди прийнятно, і в багатьох випадках ви можете залишити свої символи Unicode незмінними. Для цього встановіть ensure_ascii варіант до False:

jstr = json.dumps(data, ensure_ascii=False, indent=4)
print(jstr)
{
    "item": "Beer",
    "cost": "£4.00"
}

Пропустити спеціальні типи даних ключа

Якщо ключ у вашому словнику має непримітивний тип (str, int, float, bool or None) З TypeError виникає, коли ви намагаєтеся скопіювати вміст JSON у файл. Ви можете пропустити ці клавіші за допомогою skipkeys Аргумент:

jstr = json.dumps(data, skipkeys=True)

Увімкнення та вимкнення циклічної перевірки

Якщо властивість об’єкта JSON посилається на самого себе або на інший об’єкт, який посилається на батьківський об’єкт, створюється нескінченно рекурсивний JSON. Нескінченна рекурсія зазвичай призводить до швидкого виділення пам’яті, доки на пристрої не вичерпається пам’ять, а у випадку створення дампа JSON RecursionError піднімається і скидання припиняється.

Це регулюється check_circular прапор, який є True за замовчуванням і запобігає можливим проблемам під час написання циклічних залежностей. Щоб вимкнути його, ви можете встановити значення «False»:

jstr = json.dumps(data, check_circular=False)

Однак зауважте, що це так дуже не рекомендовано.

Увімкнення та вимкнення NaN

NaN-значення, наприклад -inf, inf та nan може проникнути в об’єкти, які потрібно серіалізувати або десеріалізувати. Стандарт JSON не дозволяє для значень NaN, але вони все ще містять логічне значення, яке ви можете передати в повідомленні. З іншого боку, можливо, ви захочете застосувати значення NaN НЕ передано, і замість цього викликає виняток. The allow_nan прапор встановлено True за замовчуванням і дозволяє серіалізувати та десеріалізувати значення NaN, замінюючи їх еквівалентами JavaScript (Inifinity, -Infinity та NaN).

Якщо встановити прапор на False натомість – ви перейдете на суворо стандартизований формат JSON, що підвищує a ValueError якщо ваші об’єкти містять атрибути з такими значеннями:

jstr = json.dumps(data, allow_nan=False)

Зміна роздільників

У JSON ключі відокремлені від значень двокрапками (:), а елементи відокремлюються один від одного комами (,):

key1:value1,
key2:value2

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


jstr = json.dumps(data, separators=(',', ':'))

Проблеми сумісності з Python 2

Якщо ви використовуєте старішу версію Python (2.x), ви можете зіткнутися з a TypeError під час спроби скинути вміст JSON у файл. Зокрема, якщо вміст містить символи, відмінні від ASCII, a TypeError піднято, навіть якщо ви передаєте аргумент кодування, коли використовуєте json.dump() метод:


with open('json_data.json', 'w', encoding='utf-8') as outfile:
    json.dump(json_string, outfile, ensure_ascii=False)

Якщо ви зіткнулися з цим крайовим випадком, який згодом було виправлено в наступних версіях Python, спробуйте використовувати json.dumps() натомість і записати вміст рядка у файл замість потокової передачі вмісту безпосередньо у файл.

Висновок

У цьому посібнику ми познайомили вас із json.dump(), json.dumps(), json.load() та json.loads() методи, які допомагають у серіалізації та десеріалізації рядків JSON.

Потім ми розглянули, як можна сортувати об’єкти JSON, красиво друкувати їх, змінювати кодування, пропускати користувальницькі ключові типи даних, увімкнути чи вимкнути циклічні перевірки та чи дозволені NaN, а також як змінити роздільники для серіалізація та десеріалізація.

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

Часова мітка:

Більше від Stackabuse