繁体   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