Python читает JSON файл и модифицирует
Привет, я пытаюсь взять данные из json файла и вставить и id, а затем выполнить POST REST.
у моего файла data.json есть:
{
'name':'myname'
}
и я хотел бы добавить идентификатор, чтобы данные json выглядели следующим образом:
{
'id': 134,
'name': 'myname'
}
Итак, я попробовал:
import json
f = open("data.json","r")
data = f.read()
jsonObj = json.loads(data)
Я не могу загрузить файл формата json.
Что я должен сделать, чтобы преобразовать json файл в json-объект и добавить другое значение id.
Ответы
Ответ 1
Задайте элемент с помощью data['id'] = ...
.
import json
with open('data.json', 'r+') as f:
data = json.load(f)
data['id'] = 134 # <--- add `id` value.
f.seek(0) # <--- should reset file position to the beginning.
json.dump(data, f, indent=4)
f.truncate() # remove remaining part
Ответ 2
Решение falsetru приятно, но имеет небольшую ошибку:
Предположим, что исходная длина "id" больше 5 символов. Когда мы сбрасываем новый "id" (134 только с тремя символами), длина строки, записанной из позиции 0 в файле, меньше более короткой, чем исходная длина. Дополнительные символы (например, '}') оставлены в файле из исходного содержимого.
Я решил, что заменив исходный файл.
import json
import os
filename = 'data.json'
with open(filename, 'r') as f:
data = json.load(f)
data['id'] = 134 # <--- add `id` value.
os.remove(filename)
with open(filename, 'w') as f:
json.dump(data, f, indent=4)
Ответ 3
Я хотел бы представить модифицированную версию решения Vadim. Это помогает обрабатывать асинхронные запросы на запись/изменение файла JSON. Я знаю, что это не было частью первоначального вопроса, но может быть полезным для других.
В случае асинхронной модификации файла os.remove(filename)
вызовет FileNotFoundError
если запросы появляются часто. Чтобы преодолеть эту проблему, вы можете создать временный файл с измененным содержимым, а затем переименовать его, заменив старую версию. Это решение прекрасно работает как для синхронных, так и для асинхронных случаев.
import os, json, uuid
filename = 'data.json'
with open(filename, 'r') as f:
data = json.load(f)
data['id'] = 134 # <--- add 'id' value.
# add, remove, modify content
# create randomly named temporary file to avoid
# interference with other thread/asynchronous request
tempfile = os.path.join(os.path.dirname(filename), str(uuid.uuid4()))
with open(tempfile, 'w') as f:
json.dump(data, f, indent=4)
# rename temporary file replacing old file
os.rename(tempfile, filename)
Ответ 4
На самом деле существует множество способов сделать это, и все вышеперечисленное так или иначе является действительным подходом... Позвольте мне добавить прямое предложение. Итак, если предположить, что ваш текущий JSON файл выглядит так...
{
"name":"myname"
}
И вы хотите добавить этот новый контент json (добавив ключ "id")
{
"id": "134",
"name": "myname"
}
Мой подход всегда состоял в том, чтобы сделать код максимально читабельным с легко отслеживаемой логикой. Итак, во-первых, мы читаем весь существующий файл json в память, предполагая, что вы очень хорошо осведомлены о существующих ключах json.
import json
# first, get the absolute path to json file
PATH_TO_JSON = 'data.json' # assuming same directory (but you can work your magic here with os.)
# read existing json to memory. you do this to preserve whatever existing data.
with open(PATH_TO_JSON,'r') as jsonfile:
json_content = json.load(jsonfile) # this is now in memory! you can use it outside 'open'
Далее мы снова используем синтаксис "с открытым()" с опцией "w". "w" - это режим записи, который позволяет нам редактировать и записывать новую информацию в файл. Вот уловка, которая работает для нас: любой существующий json с тем же целевым именем записи будет удален автоматически.
Итак, что мы можем сделать сейчас, это просто написать в то же имя файла с новыми данными
# add the id key-value pair (rmbr that it already has the "name" key value)
json_content["id"] = "134"
with open(PATH_TO_JSON,'w') as jsonfile:
json.dump(json_content, jsonfile, indent=4) # you decide the indentation level
И вот, пожалуйста! data.json должен быть хорош для старого доброго POST-запроса