Введение
В этом руководстве мы рассмотрим, как читать и записывать данные 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. stringjson.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.