Модуль JSON

Введение

Примеры

  • 1

    Создание 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}' 
  • 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]} 
  • 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) 
  • 3

    Извлечение данных из файла

    Следующий фрагмент открывает JSON закодированный файл (замените filename с действительным именем файла) и возвращает объект , который хранится в файле.

     import json
    
    with open(filename, 'r') as f:
        d = json.load(f) 
  • 1

    `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') 
  • 1

    Вызов `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 
  • 2

    Форматирование вывода 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"}]} 
  • 1

    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"} 

Синтаксис

Параметры

Примечания