如何使用python更新json文件


74

我正在尝试更新现有的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": ""
}

Answers:


118

这里的问题是您已打开文件并读取其内容,因此光标位于文件的末尾。通过写入相同的文件句柄,实际上是在追加文件。

最简单的解决方案是在读入文件后将其关闭,然后重新打开以进行写入。

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()将光标移回文件的开头然后开始写入,然后使用atruncate()来处理新数据小于前一个数据的情况。

with open("replayScript.json", "r+") as jsonFile:
    data = json.load(jsonFile)

    data["location"] = "NewPath"

    jsonFile.seek(0)  # rewind
    json.dump(data, jsonFile)
    jsonFile.truncate()

10
感谢您解释使用seek()truncate()。但是,我将通过更改jsonFile.write(json.dumps(data))jsonFile.dump(data, f);来改进此答案。更多pythonic。
BoltzmannBrain

2
如果我data["location_2"] = "NewPath_2"也要更新多个位置,那么我也应该jsonFile.seek(0); dump(); truncate()为那条线做还是只jsonFile.seek(0) ; json.dump(data, jsonFile); jsonFile.truncate()对全部更新一次做就足够了?
alper

1
是否json.dump(data, jsonFile); jsonFile.truncate()仅更新文件上的更新部分或重新写入完整文件?@Shawn Chin
alper

在第二个示例中,tmp = data["location"] 似乎是多余的;应该将其删除。另外,我使用json.dump(data,jsonFile,indent = 4)来触发漂亮打印,因此json文件布局将不是紧凑类型。
太阳熊

有没有办法只更新一个json字段,而不必重写整个文件?我只是在玩它,最后弄乱了整个文件。
anquadros

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

8
我很好奇,tmp变量有什么需要?将其传递给tmp = data ['location]与直接传递data ['location']路径有区别吗?
SMDC '18年

2
我认为这只是一个示例,显示了注释中所说的“使用缓冲内容”是如何工作的。
vchrizz
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.