如何用python更新json文件

104 人关注

我试图更新现有的Json文件,但由于某些原因,要求的值没有被改变,但整个值集(包括新的值)被追加到原始文件中。

jsonFile = open("replayScript.json", "r+")
data = json.load(jsonFile)
tmp = data["location"]
data["location"] = "NewPath"
jsonFile.write(json.dumps(data))

而结果是 。 "location": "NewPath", "Id": "0", "resultDir": "", "resultFile": "", "mode": "replay", "className": "", "method": "METHOD" "location": "/home/karim/storm/project/storm/devqa/default.xml", "Id": "0", "resultDir": "", "resultFile": "", "mode": "replay", "className": "", "method": "METHOD" "resultDir": "", "location": "pathaaaaaaaaaaaaaaaaaaaaaaaaa", "method": "METHOD", "className": "", "mode": "replay", "Id": "0", "resultFile": ""

python
json
Igal
Igal
发布于 2012-12-19
4 个回答
Shawn Chin
Shawn Chin
发布于 2022-08-28
已采纳
0 人赞同

这里的问题是,你已经打开了一个文件并读取了它的内容,所以光标在文件的末端。通过向同一个文件句柄写入,你基本上是在向文件追加内容。

最简单的解决办法是在读入文件后关闭文件,然后再重新打开进行写入。

with open("replayScript.json", "r") as jsonFile:
    data = json.load(jsonFile)
data["location"] = "NewPath"
with open("replayScript.json", "w") as jsonFile:
    json.dump(data, jsonFile)

另外,你可以使用seek()将光标移回到文件的开头,然后开始写,接着是一个truncate()来处理新数据比以前的数据小的情况。

with open("replayScript.json", "r+") as jsonFile:
    data = json.load(jsonFile)
    data["location"] = "NewPath"
    jsonFile.seek(0)  # rewind
    json.dump(data, jsonFile)
    jsonFile.truncate()
    
谢谢你解释了 seek() truncate() 的使用。然而,我想通过将 jsonFile.write(json.dumps(data)) 改为 jsonFile.dump(data, f) 来改进这个答案;更多的pythonic。
如果我也要更新多个位置,如 data["location_2"] = "NewPath_2" ,我是否也要对该行进行 jsonFile.seek(0); dump(); truncate() ,还是只对所有的更新进行单一的 jsonFile.seek(0) ; json.dump(data, jsonFile); jsonFile.truncate() 即可?
替换代码0】是只更新文件上的更新部分,还是把整个文件重新写一遍?@Shawn Chin
在第二个例子中, tmp = data["location"] 似乎是多余的;它应该被删除。另外,我使用了` json.dump(data, jsonFile, indent=4)`来触发pretty-print,这样一来,json文件的布局就不会是紧凑的类型。
有没有一种方法可以只更新一个json字段,而不必重写整个文件?我只是在玩,结果把整个文件弄得一团糟。
Igal
Igal
发布于 2022-08-28
0 人赞同
def updateJsonFile():
    jsonFile = open("replayScript.json", "r") # Open the JSON file for reading
    data = json.load(jsonFile) # Read the JSON into the buffer
    jsonFile.close() # Close the JSON file
    ## Working with buffered content
    tmp = data["location"] 
    data["location"] = path
    data["mode"] = "replay"
    ## Save our changes to JSON file
    jsonFile = open("replayScript.json", "w+")
    jsonFile.write(json.dumps(data))
    jsonFile.close()
    
SMDC
我很好奇,tmp变量的必要性是什么? 传递给tmp = data['location]与直接传递给data['location'] 路径有什么不同吗?
我想这只是一个例子,以显示 "与缓冲内容一起工作 "的可能性,正如评论所说。
RCM696
RCM696
发布于 2022-08-28
0 人赞同
def updateJsonFile():   
    with open(os.path.join(src, "replayScript.json"), "r+") as jsonFile:
        data = json.load(jsonFile)
        jsonFile.truncate(0)
        jsonFile.seek(0)
        data["src"] = "NewPath"
        json.dump(data, jsonFile, indent=4)
        jsonFile.close()
    
请添加一个简短的解释,说明它是如何/为什么解决这个问题的。
Donovan Whysong
Donovan Whysong
发布于 2022-08-28
0 人赞同
def writeConfig(key, value):
        with open('config.json') as f:
            data = json.load(f)
            # Check if key is in file
            if key in data:
                # Delete Key
                del data[key]
                cacheDict = dict(data)
                # Update Cached Dict