Баннер мобильный (3) Пройти тест

Как работать с JSON-файлами в Python

Разбираемся на простых примерах

Разбор

27 ноября 2025

Поделиться

Скопировано
Как работать с JSON-файлами в Python

Содержание

    Из этой статьи вы узнаете, что такое текстовый формат JSON и для чего он был придуман. Мы рассмотрим парочку простых нотаций в этом формате и несколько несложных примеров работы с JSON на языке программирования Python. А также научимся добавлять, изменять и удалять данные в JSON и еще кое-что интересное.

    Что такое JSON и зачем он нужен

    JSON (JavaScript Object Notation) — это текстовый формат обмена данными, основанный на синтаксисе объектов JavaScript. Он представляет информацию в виде структурированных пар «ключ‑значение», позволяя описывать сложные иерархические структуры — объекты, массивы, вложенные элементы. Формат является платформонезависимым: он может использоваться в любой операционной системе и его могут читать и обрабатывать программы на любых языках программирования.

    Основная задача JSON — обеспечивать удобный и компактный способ передачи данных между различными системами и компонентами приложений. Он широко применяется в веб‑разработке: при обмене информацией между клиентскими приложениями и серверами через API, хранении конфигурационных настроек, передаче данных в мобильных приложениях. Благодаря простоте синтаксиса и читаемости JSON стал одним из самых популярных форматов для интеграции разнородных систем.

    Примеры нотаций на JSON

    Ниже показан пример нотации, который наглядно демонстрирует всю простоту формата JSON. В примере указаны данные для некоторого вымышленного персонажа по имени Андрей:

    {
      "firstName": "Andrey",
      "lastName": "Ivanov",
      "hobbies": ["programming", "reading", "drawing"],
      "age": 42,
      "children":
        {
          "son": {
            "name": "Victor",
            "age": 7
          },
          "daughter": {
            "name": "Olga",
            "age": 12
          }
      }
    }

    Мы видим набор ключей и их значений, которые составляют основу нотаций на JSON. Такие наборы являются неупорядоченными коллекциями и называются объектами. Ключи всегда являются строками и заключаются в кавычки. Значениями ключей могут быть строки, числа, логические значения, списки или другие объекты. Объекты заключаются в фигурные скобки, а списки — в квадратные.

    Как видно из представленной выше нотации, наш Андрей носит фамилию Иванов и увлекается программированием, чтением и рисованием. Также видим, что возраст у нашего персонажа 42 года, а еще у него есть двое детей — сын Виктор семи лет и дочь Ольга 12-и лет. Или вот еще пример подобной нотации:

    {
        "planetName": "Mars",
        "group": "earth group",
        "radius": 3389.5,
        "satellites": [
            {
                "name": "Fobos"
            },
            {
                "name": "Deimos"
            }
        ]
    }

    Эта нотация составлена для планеты Марс. Приводится группа, к которой принадлежит планета, ее радиус и спутники. Как известно, у Марса всего два спутника: Фобос и Деймос.

    Загрузка и получение данных

    В языке Python имеется модуль для работы с данными в формате JSON. Импортируем его:

    import json

    И теперь мы можем пользоваться всеми функциями из этого модуля. Допустим, у нас имеется файл data.json. Чтобы загрузить данные из этого файла можно использовать функции open с параметром r (для чтения) и load:

    with open('data.json', 'r') as file:
        data = json.load(file)

    А если данные хранятся в строковом виде то в этом случае следует использовать функцию loads:

    json_string = '{"name": "Andrey", "age": 42}'
    data = json.loads(json_string)

    Эти функции преобразуют данные в словари и списки, что позволяет достаточно просто получать к ним доступ. Более подробно про списки можно прочитать в этой статье, а про словари — в этой. Вот так можно легко узнать возраст Андрея из прошлого раздела:

    print(data["age"])

    В консоли получим:

    42

    Также в файле есть так называемые вложенные структуры. Это данные детей Андрея. Их тоже довольно просто получить:

    print(data["children"]["son"]["name"])

    Получим:

    Victor

    Или для дочери:

    print(data["children"]["daughter"]["age"])

    Результат:

    12

    С помощью цикла for можно получать элементы списка. У нас как раз в качестве значения ключа hobbies содержится список из трех элементов. Вот так их можно все обойти:

    for hobby in data['hobbies']:
        print(hobby)

    В консоли будет выведено:

    programming
    reading
    drawing

    Добавление, изменение и удаление данных

    Итак, у нас есть файл data.json и мы уже знаем, как получать из него некоторые данные. Теперь давайте попробуем эти данные изменить, а может даже вообще удалить. Для начала добавим данные о работе Андрея:

    data["work"] = "Big Company"

    Чтобы проверить, что данные добавлены, делаем так:

    print(data)

    В консоли получим такой вывод:

    {'firstName': 'Andrey', 'lastName': 'Ivanov', 'hobbies': ['programming', 'reading', 'drawing'], 'age': 42, 'children': {'son': {'name': 'Victor', 'age': 7}, 'daughter': {'name': 'Olga', 'age': 12}}, 'work': 'Big Company'}

    Как видим, данные о работе успешно добавились. Теперь изменим возраст Андрея:

    data["age"] = 43

    Получим:

    {'firstName': 'Andrey', 'lastName': 'Ivanov', 'hobbies': ['programming', 'reading', 'drawing'], 'age': 43, 'children': {'son': {'name': 'Victor', 'age': 7}, 'daughter': {'name': 'Olga', 'age': 12}}, 'work': 'Big Company'}

    То есть, если мы присваиваем значение к несуществующим данным, то они добавляются, а если мы обращаемся к уже имеющимся данным и пытаемся их изменить, то они меняют свое значение. Для удаления данных применяется оператор del. Удалим, например, фамилию Андрея:

    del data["lastName"]

    Вывод в консоли будет следующий:

    {'firstName': 'Andrey', 'hobbies': ['programming', 'reading', 'drawing'], 'age': 43, 'children': {'son': {'name': 'Victor', 'age': 7}, 'daughter': {'name': 'Olga', 'age': 12}}, 'work': 'Big Company'}

    Но не стоит забывать, что мы изменили данные только в переменной data. Сам файл data.json остался без изменений. Чтобы записать данные в файл нужно применить ту же функцию open, но уже с параметром w (для записи) и вызвать еще функцию dump и ей на вход передать в качестве аргументов файл и данные:

    with open('data.json', 'w') as file:
        json.dump(data, file, indent=4)

    Параметр indent задает количество пробелов для отступов на каждом уровне вложенности в файле JSON. Это делает его более читабельным. Без этого параметра все данные будут записаны в одну строку. В результате получим файл с таким содержимым:

    {
        "firstName": "Andrey",
        "hobbies": [
            "programming",
            "reading",
            "drawing"
        ],
        "age": 43,
        "children": {
            "son": {
                "name": "Victor",
                "age": 7
            },
            "daughter": {
                "name": "Olga",
                "age": 12
            }
        },
        "work": "Big Company"
    }

    Валидация JSON

    Часто бывает полезно проверить JSON на соответствие некоторому шаблону. Узнать, все ли обязательные данные на месте и правильно заполнены. Для этого применяются JSON-схемы. Они описывают требуемую структуру и типы данных, которые должны быть в документе. Вот пример такой схемы:

    schema = {
        "type": "object",
        "properties": {
            "name": {"type": "string"},
            "age": {"type": "number"},
            "isWorker": {"type": "boolean"}
        },
        "required": ["name", "age"]
    }

    Мы видим, что документ в формате JSON может состоять из ключей name, age и isWorker, причем строго прописаны типы этих ключей. Так, для name принимается только строковый тип (string), а для age числовой (number). Ключ isWorker может принимать только логические значения (boolean). Также в required определены обязательные данные, которые должны входить в состав документа. В нашем случае это name и age. Для использования таких схем существует библиотека jsonschema. Импортируем ее:

    from jsonschema import validate, ValidationError

    Сразу после импорта прописываем нашу схему и сразу после нее приводим то, что будем проверять на валидность. Для примера возьмем вот такую простенькую нотацию:

    data = {
        "name": "Alex",
        "age": 45,
        "isWorker": True
    }

    Для проверки используется вот такая конструкция с обработкой исключений:

    try:
        validate(instance=data, schema=schema)
        print("Соответствует схеме!")
    except ValidationError as e:
        print("Не соответствует схеме:", e.message)

    Понятно, что в случае с приведенной выше нотацией проверка должна пройти успешно, так как все обязательные данные на месте и все значения указаны верно. В консоли получим:

    Соответствует схеме!

    А теперь давайте удалим данные с указанием возраста:

    data = {
        "name": "Alex",
        "isWorker": True
    }

    Получим следующий результат:

    Не соответствует схеме: 'age' is a required property

    Или же оставим age, но значение возраста укажем в строковом виде:

    data = {
        "name": "Alex",
        "age": "45",
        "isWorker": True
    }

    Результат:

    Не соответствует схеме: '45' is not of type 'number'

    Получение данных с сервера

    Многие сайты хранят свои данные в формате JSON. Например, есть вот такая страничка, где хранятся курсы валют и их довольно легко оттуда получить. Как это сделать? Для этого можно использовать библиотеку requests. Она поможет нам создать соответствующий запрос и получить данные. Подробнее о ней можно прочитать в этой нашей публикации. Импортируем библиотеку:

    import requests

    А теперь создаем GET-запрос по адресу страницы:

    data = requests.get('https://www.cbr-xml-daily.ru/daily_json.js').json()

    И далее выводим полученные данные в консоль. Для доллара США это будет выглядеть так:

    print(data['Valute']['USD'])

    Результат в консоли будет примерно такой:

    {'ID': 'R01235', 'NumCode': '840', 'CharCode': 'USD', 'Nominal': 1, 'Name': 'Доллар США', 'Value': 81.3475, 'Previous': 81.3582}

    Чтобы получить информацию по курсу евро, делаем так:

    print(data['Valute']['EUR'])

    Результат:

    {'ID': 'R01239', 'NumCode': '978', 'CharCode': 'EUR', 'Nominal': 1, 'Name': 'Евро', 'Value': 94.6656, 'Previous': 94.3845}

    Парсинг больших JSON-файлов

    На практике, довольно часто, приходится иметь дело с очень большими по объему файлами в формате JSON. Если ресурсы ограничены, то обрабатывать такие файлы лучше всего поэтапно. Для этого имеется библиотека ijson. Она предназначена для итеративного парсинга и позволяет вести обработку файлов с большими объемами данных, не загружая их полностью в память, что как раз полезно в случае с ограниченными ресурсами. Для примера возьмем тот же наш файл data.json и пропарсим данные children:

    import ijson
    
    with open('data.json', 'r') as file:
        parser = ijson.items(file, 'children')
        for children in parser:
            print(children)

    После импорта нужного модуля, открываем файл для чтения при помощи уже знакомой нам функции open. Далее посредством функции items из импортированного модуля ijson создаем переменную с именем parser. На вход функции items подаем файл и то место в файле, которое нужно пропарсить. В результате в переменной parser окажутся необходимые нам данные. А дальше циклом for пробегаемся по всем этим данным и выводим их в консоль. В консоли получим следующее:

    {'son': {'name': 'Victor', 'age': 7}, 'daughter': {'name': 'Olga', 'age': 12}}

    Данные получены.

    Превращение XML в JSON

    Кроме JSON имеются и другие форматы для хранения и передачи данных. Одним из них является XML. Он более громоздкий и в отличие от JSON его не так удобно читать. Вот пример простого XML:

     <book>
          <genre>Фантастический роман</genre>
          <title>Красная планета</title>
          <author>Роберт Хайнлайн</author>
      </book>

    В языке Python есть достаточно несложный способ превращения XML в JSON. Воспользуемся библиотекой xmltodict. Она превращает XML в словарь, который потом легко преобразовать в JSON. Для начала импортируем нужные модули:

    import xmltodict
    import json

    Создадим переменную с нашим XML:

    xml_data = """
       <book>
           <genre>Фантастический роман</genre>
           <title>Красная планета</title>
           <author>Роберт Хайнлайн</author>
       </book>
    """

    С помощью функции parse из модуля xmltodict превращаем XML в словарь:

    data = xmltodict.parse(xml_data)

    И теперь мы можем полученный словарь легко превратить в JSON при помощи функции dumps из модуля json:

    result = json.dumps(data, indent=2, ensure_ascii=False)

    Обратим внимание на следующее: в одном из прошлых разделов мы использовали функцию dump для записи данных в ФАЙЛ JSON. Функция dumps преобразует данные в СТРОКУ в формате JSON. Сравним с load и loads: функция load использовалась нами для получения данных из ФАЙЛА, а при помощи loads мы получали данные из СТРОКИ. Окончание «s» у названных функций как раз указывает на то, что они работают со строками. Выводим результат в консоль:

    print(result)

    В нашем случае результат в консоли будет таким:

    {
      "book": {
        "genre": "Фантастический роман",
        "title": "Красная планета",
        "author": "Роберт Хайнлайн"
      }
    }

    Задание для самостоятельного выполнения

    Ранее было показано, как получить с сервера данные о курсах валют. Получите такие данные для юаня. Далее получите текущее значение курса и предыдущее его значение.

    Так как юань обозначается аббревиатурой CNY, то код будет таким:

    import requests
    
    data = requests.get('https://www.cbr-xml-daily.ru/daily_json.js').json()
    print(data['Valute']['CNY'])

    Вывод:

    {'ID': 'R01375', 'NumCode': '156', 'CharCode': 'CNY', 'Nominal': 1, 'Name': 'Юань', 'Value': 11.0648, 'Previous': 11.3079}

    Значение текущего курса содержится в ключе Value и чтобы его получить надо сделать так:

    print(data['Valute']['CNY']['Value'])

    Результат:

    11.0648

    А предыдущее значение курса находится в ключе Previous. Меняем Value на Previous:

    print(data['Valute']['CNY']['Previous'])

    Получим:

    11.3079

    Разбор

    Поделиться

    Скопировано
    0 комментариев
    Комментарии