Модуль 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"} 

Синтаксис

Параметры

Примечания