Чтение и запись JSON в файл в Python

Введение

В этом руководстве мы рассмотрим, как читать и записывать данные JSON из файла и в файл в Python, используя json модуль.

JSON (нотация объектов JavaScript) является чрезвычайно популярным форматом для сериализации данных, учитывая его универсальность и легкость, а также он довольно удобен для человека. В частности, он широко используется в мире веб-разработки, где вы, вероятно, столкнетесь с сериализованными объектами JSON, отправляемыми из API REST, конфигурация приложения или даже простое хранилище данных.

Учитывая его распространенность, чтение и анализ файлов JSON (или строк) довольно распространены, и запись JSON для отправки не менее распространена. В этом руководстве мы рассмотрим, как использовать json модуль для чтения и записи JSON в Python.

Запись JSON в файл с помощью Python с помощью json.dump() и json.dumps()

Чтобы записать содержимое JSON в файл на Python, мы можем использовать json.dump() и json.dumps(), Эти отдельные методы и добиться другого результата:

  • json.dumps() – Сериализирует объект в формате JSON. string
  • json.dump() – сериализовал объект в поток JSON для сохранения в файлы или сокеты.

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

Естественный формат JSON похож на карта в информатике – карта key-value пары. В Питоне словарь является реализацией карты, поэтому мы, естественно, сможем точно представлять JSON через dict. Словарь может содержать другие вложенные словари, массивы, логические значения или другие примитивные типы, такие как целые числа и строки.

:::

Примечание: Встроенный JSON package предлагает несколько удобных методов, которые позволяют нам конвертировать между 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, каждый из которых имеет name, department и place, dumps() функции json модуль свалках словарь в содержимое JSON и возвращает Строка JSON.

После сериализации вы можете решить отправить его в другую службу, которая его десериализует или, скажем, сохранит. Чтобы сохранить эту строку JSON в файле, мы просто откроем файл в режиме записи и запишем его. Если вы не хотите извлекать данные в независимую переменную для последующего использования, а хотите просто выгрузить их в файл, вы можете пропустить dumps() функция и использование dump() вместо:


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. не передается и вместо этого вызывает исключение. allow_nan флаг установлен на True по умолчанию и позволяет сериализовать и десериализовать значения NaN, заменяя их эквивалентами JavaScript (Inifinity, -Infinity и NaN).

Если установить флаг False вместо этого вы переключитесь на строго стандартизированный формат JSON, что вызывает 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) — вы можете столкнуться с TypeError при попытке сбросить содержимое JSON в файл. А именно, если содержимое содержит не-ASCII-символ, 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 является одним из самых популярных способов сериализации структурированных данных, вам, вероятно, придется взаимодействовать с ним довольно часто, особенно при работе с веб-приложениями. питона json модуль - отличный способ начать работу, хотя вы, вероятно, обнаружите, что простой — еще одна отличная альтернатива, гораздо менее строгая к синтаксису JSON.

Отметка времени:

Больше от Стекабьюс