Чтение и запись в файл JSON-объекта

Мини-задача на разогрев: являются ли две строки анаграммами?

Эта статья научит вас парсить данные из JSON. Также вы узнаете, как читать и записывать в файл данные JSON.


За последние 5-10 лет формат JSON был одним из самых популярных способов сериализации данных (если не самым популярным). Особенно в веб-разработке. С этим форматом вы столкнетесь при работе с REST API, конфигурациями приложений или базами данных.

Хотите скачать книги по Python в 2 клика? Тогда вам в наш телеграм канал PythonBooks 

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

Запись JSON в файл

Самый простой способ записать JSON в файл — использовать словарь. Они могут хранить вложенные словари, массивы, булевы значения и другие типы данных вроде целых чисел и строк. Более детальный список поддерживаемых типов данных можно найти здесь

Во встроенной библиотеке json есть «волшебный» метод, который позволяет конвертировать словари в сериализованную JSON-строку.

import json

data = {}
data['people'] = []
data['people'].append({
    'name': 'Scott',
    'website': 'pythonist.ru',
    'from': 'Nebraska'
})
data['people'].append({
    'name': 'Larry',
    'website': 'pythonist.ru',
    'from': 'Michigan'
})
data['people'].append({
    'name': 'Tim',
    'website': 'pythonist.ru',
    'from': 'Alabama'
})

with open('data.txt', 'w') as outfile:
    json.dump(data, outfile)

После импорта библиотеки json мы объявляем несколько словарей и наполняем их данными. Самая важная часть — в конце программы. Здесь мы используем оператор with, чтобы открыть файл. После этого мы используем метод json.dump, чтобы записать наши словари в файл. 

Вторым аргументом может быть любой файлоподобный объект — даже если это не совсем файл. Например, сокет. Его можно открыть, закрыть и записать так же, как и файл. С подобным вариантом использования JSON вы точно столкнетесь — это важно запомнить. 

Стоит упомянуть и о вариации метода json.dumpjson.dumps. Этот метод позволяет вернуть JSON-строку, а не записывать ее в файл. Это может быть полезно, если вы хотите изменить JSON-строку. (например, зашифровать)

Чтение JSON из файла

Чтение JSON из файла такое же простое, как и запись. С помощью библиотеки json мы можем спарсить JSON-строку прямо из файла. В этом примере мы парсим данные и выводим их в консоль:

import json

with open('data.txt') as json_file:
    data = json.load(json_file)
    for p in data['people']:
        print('Name: ' + p['name'])
        print('Website: ' + p['website'])
        print('From: ' + p['from'])
        print('')

json.load — очень важный метод, запомните его. С его помощью происходит чтение файла, парс JSON-данных. После этого все данные записываются в словарь и возвращаются вам. 

Как и у json.dump, у json.load есть дополнительный метод. Он позволяет работать со строками напрямую, ведь чаще всего у вас не будет файлоподобного объекта, содержащего JSON. Как вы уже догадались, называется он json.loads. Допустим, вы вызываете конечную точку REST с помощью GET, который возвращает строку. Ее мы и можем напрямую передать в json.loads.

Параметры

При сериализации данных в JSON могут возникнуть проблемы. Например, его будет не очень удобно читать, ведь удаляются все пробелы. В большинстве случаев этот вариант вполне хорош, но порой нужно внести небольшие изменения. К примеру, добавить пробелы, чтобы JSON было удобнее читать. У json.load и json.dump есть несколько параметров, которые дают необходимую гибкость. О некоторых из них мы и поговорим.

Pretty-Printing

Сделать JSON более удобочитаемым (pretty-printing) — очень просто. Нужно лишь передать целое число в параметр indent

import json
data = {'people':[{'name': 'Scott', 'website': 'pythonist.ru', 'from': 'Nebraska'}]}
json.dumps(data, indent=4)
{
    "people": [
        {
            "website": "pythonist.ru", 
            "from": "Nebraska", 
            "name": "Scott"
        }
    ]
}

Это довольно полезно. Особенно если вам часто приходится читать JSON во время работы. Также вы можете использовать использовать команду json.tool прямо в командной строке. Если вы хотите удобочитаемый JSON, наберите в командной строке следующий код:

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

Сортировка

В JSON объект определяется следующим образом:

Объект — это неупорядоченный набор пар ключ/значение.

То есть, порядок не гарантируется. Но навести его реально. Сделать это можно с помощью передачи True в параметр sort_keys в методах json.dump или json.dumps.

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

ASCII-текст

По умолчанию json.dump проверяет, имеет ли ваш текст в словаре кодировку 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"
}