Как дополнить json файл
У меня имеется вот такой код:
import json
for i in range(3):
b = [{'name': i,'year': i+1}]
print(b)
with open('json.json', 'w+', encoding='utf-8') as file:
json.dump(b,file,indent=4, ensure_ascii=False)
Мне нужно чтобы на выходе я получил
[
{
"name": 0,
"year": 1
},
{
"name": 1,
"year": 2
},
{
"name": 2,
"year": 3
}
]
Но я получаю это
[
{
"name": 2,
"year": 3
}
]
Как мне нужно изменить код, что бы я получил нужный мне результат?
Ответы (2 шт):
Проблема заключается в том, что в текущем коде каждый раз открывается файл и записывается только одно значение b в файле. Из-за этого предыдущие данные перезаписываются на каждом шаге цикла. Чтобы добиться нужного результата, нужно создать список для всех объектов и записать его в файл один раз.
Вот исправленный код:
import json
result = []
for i in range(3):
result.append({'name': i, 'year': i + 1})
with open('json.json', 'w+', encoding='utf-8') as file:
json.dump(result, file, indent=4, ensure_ascii=False)
Если нужно именно дополнять файл, а не предварительно накопить все данные, то можно:
- извлекать текущие данные из файла
- добавлять элемент в список
- перезаписывать файл новым списком
- повторять процесс для следующего элемента
Это будет актуально, если требуется дополнять список в разных частях программы, а не в рамках одного цикла - где предварительный сбор выгоднее и проще. Можно использовать класс для хранилища, чтобы его экземпляр передавать в требуемые функции/классы.
Пример для хранения и накопления данных в списке внутри json-а:
import json
class ListStorage:
def __init__(self, file_path):
self.file_path = file_path
def add_item(self, item):
data = self.read_file()
data.extend(self._convert_to_list(item))
self.write_file(data)
def read_file(self):
with open(self.file_path, 'r', encoding='utf-8') as f:
try:
data = json.load(f)
except json.decoder.JSONDecodeError:
data = []
return self._convert_to_list(data)
def write_file(self, data):
with open(self.file_path, 'w', encoding='utf-8') as f:
json.dump(self._convert_to_list(data), f, indent=4, ensure_ascii=False)
@staticmethod
def _convert_to_list(data):
if not isinstance(data, list):
data = [data]
return data
Использование:
storage = ListStorage('json.json')
a = {'name': 'a', 'year': 1}
storage.add_item(a)
b = [{'name': 'b', 'year': 2}]
storage.add_item(b)
cd = [{'name': 'c', 'year': 3}, {'name': 'd', 'year': 4}]
storage.add_item(cd)
Результат:
[
{
"name": "a",
"year": 1
},
{
"name": "b",
"year": 2
},
{
"name": "c",
"year": 3
},
{
"name": "d",
"year": 4
}
]