Модуль JSON
Введение
Примеры
Создание JSON из Python dict
import json
d = {
'foo': 'bar',
'alice': 1,
'wonderland': [1, 2, 3]
}
json.dumps(d)
Вышеприведенный фрагмент вернет следующее:
'{"wonderland": [1, 2, 3], "foo": "bar", "alice": 1}'
Создание Python dict из JSON
import json
s = '{"wonderland": [1, 2, 3], "foo": "bar", "alice": 1}'
json.loads(s)
Вышеприведенный фрагмент вернет следующее:
{u'alice': 1, u'foo': u'bar', u'wonderland': [1, 2, 3]}
Хранение данных в файле
Следующий фрагмент кодирует данные , хранящиеся в d
в формате JSON и сохраняет его в файл (замените filename
с действительным именем файла).
import json
d = {
'foo': 'bar',
'alice': 1,
'wonderland': [1, 2, 3]
}
with open(filename, 'w') as f:
json.dump(d, f)
Извлечение данных из файла
Следующий фрагмент открывает JSON закодированный файл (замените filename
с действительным именем файла) и возвращает объект , который хранится в файле.
import json
with open(filename, 'r') as f:
d = json.load(f)
`load` vs` load`, `dump` vs` dumps`
json
модуль содержит функции для чтения и записи и из Юникода строк, и чтения и записи в файлах. Они различаются по замыкающей s
в имени функции. В этих примерах мы используем объект StringIO, но те же функции применимы для любого файлового объекта.
Здесь мы используем строковые функции:
import json
data = {u"foo": u"bar", u"baz": []}
json_string = json.dumps(data)
# u'{"foo": "bar", "baz": []}'
json.loads(json_string)
# {u"foo": u"bar", u"baz": []}
И здесь мы используем файловые функции:
import json
from io import StringIO
json_file = StringIO()
data = {u"foo": u"bar", u"baz": []}
json.dump(data, json_file)
json_file.seek(0) # Seek back to the start of the file before reading
json_file_content = json_file.read()
# u'{"foo": "bar", "baz": []}'
json_file.seek(0) # Seek back to the start of the file before reading
json.load(json_file)
# {u"foo": u"bar", u"baz": []}
Как вы можете видеть, основное отличие состоит в том, что при выгрузке данных JSON вы должны передать дескриптор файла в функцию, а не захватывать возвращаемое значение. Также стоит отметить, что вы должны искать начало файла перед чтением или записью, чтобы избежать повреждения данных. При открытии файла курсор находится в положении 0
, поэтому ниже также будет работать:
import json
json_file_path = './data.json'
data = {u"foo": u"bar", u"baz": []}
with open(json_file_path, 'w') as json_file:
json.dump(data, json_file)
with open(json_file_path) as json_file:
json_file_content = json_file.read()
# u'{"foo": "bar", "baz": []}'
with open(json_file_path) as json_file:
json.load(json_file)
# {u"foo": u"bar", u"baz": []}
Имея оба способа работы с данными JSON позволяет идиоматически и эффективно работать с форматами , которые строят на JSON, такие как pyspark
«s JSON-за линии:
# loading from a file
data = [json.loads(line) for line in open(file_path).splitlines()]
# dumping to a file
with open(file_path, 'w') as json_file:
for item in data:
json.dump(item, json_file)
json_file.write('\n')
Вызов `json.tool` из командной строки для вывода вывода в формате JSON
Учитывая некоторый файл JSON "foo.json", например:
{"foo": {"bar": {"baz": 1}}}
мы можем вызвать модуль непосредственно из командной строки (передавая имя файла в качестве аргумента), чтобы его напечатать довольно:
$ python -m json.tool foo.json
{
"foo": {
"bar": {
"baz": 1
}
}
}
Модуль также будет принимать входные данные от STDOUT, поэтому (в Bash) мы в равной степени могли бы сделать:
$ cat foo.json | python -m json.tool
Форматирование вывода JSON
Допустим, у нас есть следующие данные:
>>> data = {"cats": [{"name": "Tubbs", "color": "white"}, {"name": "Pepper", "color": "black"}]}
Просто сброс этого как JSON здесь не делает ничего особенного:
>>> print(json.dumps(data))
{"cats": [{"name": "Tubbs", "color": "white"}, {"name": "Pepper", "color": "black"}]}
Установка отступа, чтобы получить более красивый вывод
Если мы хотим , красивая печать, мы можем установить indent
размер:
>>> print(json.dumps(data, indent=2))
{
"cats": [
{
"name": "Tubbs",
"color": "white"
},
{
"name": "Pepper",
"color": "black"
}
]
}
Сортировка ключей по алфавиту для получения последовательного вывода
По умолчанию порядок ключей в выводе не определен. Мы можем получить их в алфавитном порядке, чтобы всегда получать одинаковый вывод:
>>> print(json.dumps(data, sort_keys=True))
{"cats": [{"color": "white", "name": "Tubbs"}, {"color": "black", "name": "Pepper"}]}
Избавляемся от пробелов, чтобы получить компактный вывод
Мы могли бы хотеть , чтобы избавиться от ненужных пространств, которое осуществляется путем установки разделителей строк , отличные от значения по умолчанию ', '
и ': '
:
>>>print(json.dumps(data, separators=(',', ':')))
{"cats":[{"name":"Tubbs","color":"white"},{"name":"Pepper","color":"black"}]}
JSON-кодирование пользовательских объектов
Если мы просто попробуем следующее:
import json
from datetime import datetime
data = {'datetime': datetime(2016, 9, 26, 4, 44, 0)}
print(json.dumps(data))
мы получаем ошибки говоря TypeError: datetime.datetime(2016, 9, 26, 4, 44) is not JSON serializable
.
Чтобы правильно сериализовать объект datetime, нам нужно написать собственный код для его преобразования:
class DatetimeJSONEncoder(json.JSONEncoder):
def default(self, obj):
try:
return obj.isoformat()
except AttributeError:
# obj has no isoformat method; let the builtin JSON encoder handle it
return super(DatetimeJSONEncoder, self).default(obj)
а затем использовать этот класс кодировщика вместо json.dumps
:
encoder = DatetimeJSONEncoder()
print(encoder.encode(data))
# prints {"datetime": "2016-09-26T04:44:00"}