Добавление данных в json файл в Python - программирование
Подтвердить что ты не робот

Добавление данных в json файл в Python

Я пытаюсь создать функцию, которая будет добавлять записи в файл JSON. В конце концов, я хочу файл, который выглядит как

[{"name" = "name1", "url" = "url1"}, {"name" = "name2", "url" = "url2"}]

и т.д. Вот что у меня есть:

def add(args):
    with open(DATA_FILENAME, mode='r', encoding='utf-8') as feedsjson:
        feeds = json.load(feedsjson)
    with open(DATA_FILENAME, mode='w', encoding='utf-8') as feedsjson:
        entry = {}
        entry['name'] = args.name
        entry['url'] = args.url
        json.dump(entry, feedsjson)

Это создает запись, такую как {"name"="some name", "url"="some url"}. Но если я снова использую эту функцию add с другим именем и URL, первая будет перезаписана. Что мне нужно сделать, чтобы добавить вторую (третью...) запись к первой?

РЕДАКТИРОВАТЬ: Первые ответы и комментарии к этому вопросу указали на очевидный факт, что я не использую feeds в блоке записи. Я не вижу, как это сделать, хотя. Например, следующее явно не подойдет:

with open(DATA_FILENAME, mode='a+', encoding='utf-8') as feedsjson:
    feeds = json.load(feedsjson)
    entry = {}
    entry['name'] = args.name
    entry['url'] = args.url
    json.dump(entry, feeds)
4b9b3361

Ответ 1

Вероятно, вы хотите использовать список JSON вместо словаря в качестве элемента верхнего уровня.

Итак, инициализируйте файл пустым списком:

with open(DATA_FILENAME, mode='w', encoding='utf-8') as f:
    json.dump([], f)

Затем вы можете добавить новые записи в этот список:

with open(DATA_FILENAME, mode='w', encoding='utf-8') as feedsjson:
    entry = {'name': args.name, 'url': args.url}
    feeds.append(entry)
    json.dump(feeds, feedsjson)

Обратите внимание, что это будет медленным, потому что вы будете переписывать полное содержимое файла каждый раз, когда вы вызываете add. Если вы вызываете его в цикле, подумайте о том, чтобы добавить все фиды в список заранее, а затем записать список за один раз.

Ответ 2

json может не быть лучшим выбором для форматов на диске; Проблема, связанная с добавлением данных, является хорошим примером того, почему это может быть. В частности, объекты json имеют синтаксис, который означает, что весь объект должен быть прочитан и проанализирован, чтобы понять любую его часть.

К счастью, есть много других вариантов. Особенно простой - CSV; который хорошо поддерживается стандартной библиотекой python. Самым большим недостатком является то, что он хорошо работает только для текста; он требует дополнительных действий со стороны программиста для преобразования значений в числа или другие форматы, если это необходимо.

Другим вариантом, который не имеет этого ограничения, является использование базы данных sqlite, которая также имеет встроенную поддержку в python. Это, вероятно, будет большим отступлением от кода, который у вас уже есть, но он более естественно поддерживает модель "изменить немного", которую вы, по-видимому, пытаетесь построить.

Ответ 3

Добавить запись к содержимому файла, если файл существует, в противном случае добавить запись в пустой список и записать в файл:

a = []
if not os.path.isfile(fname):
    a.append(entry)
    with open(fname, mode='w') as f:
        f.write(json.dumps(a, indent=2))
else:
    with open(fname) as feedsjson:
        feeds = json.load(feedsjson)

    feeds.append(entry)
    with open(fname, mode='w') as f:
        f.write(json.dumps(feeds, indent=2))

Ответ 4

Использование a вместо w должно позволить вам обновить файл вместо создания нового/перезаписать все в существующем файле.

См. этот ответ для разницы в режимах.

Ответ 5

Одним из возможных решений является конкатенация вручную, вот несколько полезных кодов:

import json
def append_to_json(_dict,path): 
    with open(path, 'ab+') as f:
    f.seek(0,2)                                #Go to the end of file    
    if f.tell() == 0 :                         #Check if file is empty
        f.write(json.dumps([_dict]).encode())  #If empty, write an array
    else :
        f.seek(-1,2)           
        f.truncate()                           #Remove the last character, open the array
        f.write(' , '.encode())                #Write the separator
        f.write(json.dumps(_dict).encode())    #Dump the dictionary
        f.write(']'.encode())                  #Close the array

При редактировании файла вне скрипта следует соблюдать осторожность, чтобы в конце не добавлять пробелы.

Ответ 6

Вы никогда не пишете ничего, что связано с данными, которые вы читаете. Вы хотите добавить структуру данных в каналы к новой, которую вы создаете?

Или, возможно, вы хотите открыть файл в режиме добавления open(filename, 'a'), а затем добавить свою строку, написав строку, созданную json.dumps, вместо использования json.dump, но nneonneo указывает, что это будет недействительным json.

Ответ 7

У меня есть некоторый код, который похож, но не переписывает все содержимое каждый раз. Это предназначено для периодического запуска и добавления записи JSON в конец массива.

Если файл еще не существует, он создает его и выгружает JSON в массив. Если файл уже создан, он доходит до конца, заменяет ] на a , сбрасывает новый объект JSON, а затем снова закрывает его другим ]

# Append JSON object to output file JSON array
fname = "somefile.txt"
if os.path.isfile(fname):
    # File exists
    with open(fname, 'a+') as outfile:
        outfile.seek(-1, os.SEEK_END)
        outfile.truncate()
        outfile.write(',')
        json.dump(data_dict, outfile)
        outfile.write(']')
else: 
    # Create file
    with open(fname, 'w') as outfile:
        array = []
        array.append(data_dict)
        json.dump(array, outfile)