programing

json 파일에 데이터를 추가하는 방법

codeshow 2023. 3. 8. 21:37
반응형

json 파일에 데이터를 추가하는 방법

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)

온디스크 포맷에는 json이 적합하지 않을 수 있습니다.데이터 추가 시 발생하는 문제는 왜 그런지를 보여주는 좋은 예입니다.특히 json 개체에는 전체 개체를 읽고 구문 분석해야 하는 구문이 있습니다.

다행히도, 다른 많은 선택지가 있습니다.특히 간단한 것은 CSV입니다. CSV는 python의 표준 라이브러리에서 잘 지원됩니다.가장 큰 단점은 텍스트에서만 잘 작동한다는 것입니다. 프로그래머 측에서 값을 숫자나 다른 형식으로 변환하기 위해 필요한 경우 추가적인 작업이 필요합니다.

이 제한이 없는 다른 옵션은 sqlite 데이터베이스를 사용하는 것입니다. sqlite 데이터베이스는 python에 내장되어 있습니다.이것은 이미 가지고 있는 코드와는 큰 차이가 될 것입니다만, 보다 자연스럽게 「약간의 수정」모델을 서포트하고 있습니다.

최상위 요소로 사전 대신 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루프에서 호출할 경우 사전에 모든 피드를 목록에 추가한 후 목록을 한 번에 작성하는 것이 좋습니다.

파일이 있는 경우 파일 내용에 엔트리를 추가하고, 그렇지 않은 경우 엔트리를 빈 목록에 추가한 후 파일에 씁니다.

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))

사용.a대신w기존 파일의 모든 내용을 덮어쓰거나 새 파일을 만드는 대신 파일을 업데이트할 수 있습니다.

모드의 차이에 대해서는, 회답을 참조해 주세요.

가능한 해결책 중 하나는 수동으로 연결을 수행하는 것입니다. 다음은 유용한 코드입니다.

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

스크립트 외부에서 파일을 편집할 때는 마지막에 공백이 추가되지 않도록 주의해야 합니다.

이것, 나를 위해 일해라:

with open('file.json', 'a') as outfile:
    outfile.write(json.dumps(data))
    outfile.write(",")
    outfile.close()

비슷한 코드를 가지고 있지만 매번 전체 내용을 다시 쓰지는 않습니다.이는 정기적으로 실행되고 어레이 끝에 JSON 엔트리를 추가하는 것을 의미합니다.

파일이 아직 존재하지 않으면 파일이 생성되고 JSON이 배열로 덤프됩니다.파일이 이미 생성되어 있는 경우는, 파일이 끝까지 이동해, 이 파일을 치환합니다.]와 함께,새로운 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)

당신은 당신이 읽은 데이터로 아무것도 쓰지 않습니다.새로 만들고 있는 피드에 데이터 구조를 추가하시겠습니까?

또는 추가 모드에서 파일을 열 수 있습니다.open(filename, 'a')그 다음에 스트링을 추가합니다.json.dumps사용하는 대신json.dump- 하지만 nneonneo는 이것이 유효하지 않은 json이라고 지적합니다.

import jsonlines

object1 = {
               "name": "name1",
               "url": "url1"
          }

object2 = {
               "name": "name2",
               "url": "url2"
          }   


# filename.jsonl is the name of the file
with jsonlines.open("filename.jsonl", "a") as writer:   # for writing
    writer.write(object1)
    writer.write(object2)

with jsonlines.open('filename.jsonl') as reader:      # for reading
    for obj in reader:
        print(obj)             

자세한 것은, https://jsonlines.readthedocs.io/en/latest/ 를 참조해 주세요.

소스 파일에서 데이터를 가져와 읽고 변수에 추가할 내용을 저장하기만 하면 됩니다.그런 다음 대상 파일을 열고 내부의 목록 데이터를 새 변수에 할당한 다음(아마 모두 유효한 JSON이 될 수 있음), 이 목록 변수의 '추가' 함수를 사용하여 첫 번째 변수를 추가합니다.비올라, 당신은 JSON 목록에 첨부했습니다.이제 새로 추가된 목록(JSON)으로 대상 파일을 덮어씁니다.

'open' 함수의 'a' 모드는 파일 끝에 모든 것을 부착하여 유효하지 않은 JSON 형식이 되기 때문에 여기서는 작동하지 않습니다.

다음과 같은 구술이 있다고 칩시다.

d1 = {'a': 'apple'}
d2 = {'b': 'banana'}
d3 = {'c': 'carrot'}

다음과 같이 결합 json으로 변환할 수 있습니다.

master_json = str(json.dumps(d1))[:-1]+', '+str(json.dumps(d2))[1:-1]+', '+str(json.dumps(d3))[1:]

따라서 json 파일에 추가하는 코드는 다음과 같습니다.

        dict_list = [d1, d2, d3]
        for i, d in enumerate(d_list):
            if i == 0:
                #first dict
                start = str(json.dumps(d))[:-1]
                with open(str_file_name, mode='w') as f:
                    f.write(start)
            else:
                with open(str_file_name, mode='a') as f:
                    if i != (len(dict_list) - 1):
                        #middle dicts
                        mid = ','+str(json.dumps(d))[1:-1]
                        f.write(mid)
                    else:
                        #last dict
                        end = ','+str(json.dumps(d))[1:]
                        f.write(end)

언급URL : https://stackoverflow.com/questions/12994442/how-to-append-data-to-a-json-file

반응형