简体   繁体   English

Python读取JSON文件并修改

[英]Python read JSON file and modify

Hi I am trying to take the data from a json file and insert and id then perform POST REST.嗨,我正在尝试从 json 文件中获取数据并插入和 id,然后执行 POST REST。 my file data.json has:我的文件 data.json 有:

{
    'name':'myname'
}

and I would like to add an id so that the json data looks like:我想添加一个 id,以便 json 数据如下所示:

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

So I tried:所以我试过:

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

I can't get to load the json format file.我无法加载 json 格式文件。 What should I do so that I can convert the json file into json object and add another id value.我该怎么做才能将 json 文件转换为 json 对象并添加另一个 id 值。

Set item using data['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's solution is nice, but has a little bug: falsetru 的解决方案很好,但有一个小错误:

Suppose original 'id' length was larger than 5 characters.假设原始 'id' 长度大于 5 个字符。 When we then dump with the new 'id' (134 with only 3 characters) the length of the string being written from position 0 in file is shorter than the original length.当我们使用新的“id”(134 个只有 3 个字符)转储时,从文件中的位置 0 写入的字符串的长度比原始长度 Extra chars (such as '}') left in file from the original content.原始内容在文件中留下的额外字符(例如“}”)。

I solved that by replacing the original file.我通过替换原始文件解决了这个问题。

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)

I would like to present a modified version of Vadim's solution.我想介绍 Vadim 解决方案的修改版本。 It helps to deal with asynchronous requests to write/modify json file.它有助于处理写入/修改 json 文件的异步请求。 I know it wasn't a part of the original question but might be helpful for others.我知道这不是原始问题的一部分,但可能对其他人有帮助。

In case of asynchronous file modification os.remove(filename) will raise FileNotFoundError if requests emerge frequently.在异步文件修改的情况下,如果请求频繁出现, os.remove(filename)将引发FileNotFoundError To overcome this problem you can create temporary file with modified content and then rename it simultaneously replacing old version.为了克服这个问题,您可以创建具有修改内容的临时文件,然后同时重命名替换旧版本。 This solution works fine both for synchronous and asynchronous cases.此解决方案适用于同步和异步情况。

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)

There is really quite a number of ways to do this and all of the above are in one way or another valid approaches... Let me add a straightforward proposition.确实有很多方法可以做到这一点,以上所有方法都是以一种或另一种有效的方法......让我添加一个简单的命题。 So assuming your current existing json file looks is this....因此,假设您当前现有的 json 文件看起来是这样的....

{
     "name":"myname"
}

And you want to bring in this new json content (adding key "id")并且你想引入这个新的json内容(添加键“id”)

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

My approach has always been to keep the code extremely readable with easily traceable logic.我的方法一直是通过易于跟踪的逻辑来保持代码的可读性。 So first, we read the entire existing json file into memory, assuming you are very well aware of your json's existing key(s).因此,首先,我们将整个现有的 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'

Next, we use the 'with open()' syntax again, with the 'w' option.接下来,我们再次使用 'with open()' 语法和 'w' 选项。 'w' is a write mode which lets us edit and write new information to the file. 'w' 是一种写入模式,可让我们编辑新信息并将新信息写入文件。 Here s the catch that works for us ::: any existing json with the same target write name will be erased automatically.这是对我们有用的捕获 ::: 任何具有相同目标写入名称的现有 json 都将被自动删除。

So what we can do now, is simply write to the same filename with the new data所以我们现在可以做的就是将新数据写入相同的文件名

# 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

And there you go!你去吧! data.json should be good to go for an good old POST request data.json 应该很适合处理一个很好的旧 POST 请求

try this script:试试这个脚本:

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

the result is:结果是:

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

Just the arrangement is different, You can solve the problem by converting the "data" type to a list, then arranging it as you wish, then returning it and saving the file, like that:只是排列方式不同,您可以通过将“数据”类型转换为列表,然后根据需要进行排列,然后返回并保存文件来解决问题,如下所示:

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)

the result is:结果是:

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

you can add if condition in order not to repeat the key, just change it, like that:您可以添加 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)

This implementation should suffice:这个实现应该足够了:

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

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

using context manager for the opening of the jsonfile.使用上下文管理器打开 jsonfile。 data holds the updated object and dumped into the overwritten jsonfile in 'w' mode. data 保存更新的对象并以“w”模式转储到覆盖的 jsonfile 中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM