簡體   English   中英

Python讀取JSON文件並修改

[英]Python read JSON file and modify

嗨,我正在嘗試從 json 文件中獲取數據並插入和 id,然后執行 POST REST。 我的文件 data.json 有:

{
    'name':'myname'
}

我想添加一個 id,以便 json 數據如下所示:

 {
     'id': 134,
     'name': 'myname'
 }

所以我試過:

import json
f = open("data.json","r")
data = f.read()
jsonObj = json.loads(data)

我無法加載 json 格式文件。 我該怎么做才能將 json 文件轉換為 json 對象並添加另一個 id 值。

使用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

falsetru 的解決方案很好,但有一個小錯誤:

假設原始 'id' 長度大於 5 個字符。 than the original length.當我們使用新的“id”(134 個只有 3 個字符)轉儲時,從文件中的位置 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)

我想介紹 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)

確實有很多方法可以做到這一點,以上所有方法都是以一種或另一種有效的方法......讓我添加一個簡單的命題。 因此,假設您當前現有的 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'

接下來,我們再次使用 'with 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 請求

試試這個腳本:

with open("data.json") as f:
    data = json.load(f)
    data["id"] = 134
    json.dump(data, open("data.json", "w"), indent = 4)

結果是:

{
    "name":"mynamme",
    "id":134
}

只是排列方式不同,您可以通過將“數據”類型轉換為列表,然后根據需要進行排列,然后返回並保存文件來解決問題,如下所示:

index_add = 0
with open("data.json") as f:
    data = json.load(f)
    data_li = [[k, v] for k, v in data.items()]
    data_li.insert(index_add, ["id", 134])
    data = {data_li[i][0]:data_li[i][1] for i in range(0, len(data_li))}
    json.dump(data, open("data.json", "w"), indent = 4)

結果是:

{
    "id":134,
    "name":"myname"
}

您可以添加 if 條件以免重復鍵,只需更改它,如下所示:

index_add = 0
n_k = "id"
n_v = 134
with open("data.json") as f:
    data = json.load(f)
    if n_k in data:
        data[n_k] = n_v
    else:
       data_li = [[k, v] for k, v in data.items()]
       data_li.insert(index_add, [n_k, n_v])
       data = {data_li[i][0]:data_li[i][1] for i in range(0, len(data_li))}
    json.dump(data, open("data.json", "w"), indent = 4)

這個實現應該足夠了:

with open(jsonfile, 'r') as file:
    data = json.load(file)
    data[id] = value

with open(jsonfile, 'w') as file:
    json.dump(data, file)

使用上下文管理器打開 jsonfile。 data 保存更新的對象並以“w”模式轉儲到覆蓋的 jsonfile 中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM