提前:我为模糊的问题和长篇描述道歉。我无法为我的生活指出问题而我现在绝望了。
这是一个旨在在命令行上运行的小程序。它允许用户添加或更新条目。这些条目是字典的键值对 - 它最初是与名为info.txt
的脚本位于同一级别的文本文件,必须使用" {}"进行实例化。 (糟糕的程序,我知道。我以后会解决问题)。总之,它读取文本文件,将其转换为JSON对象进行操作,然后写回文本文件。
剧本:
import os
import json
import sys
def addNew():
with open(os.path.join(os.path.abspath(os.path.dirname(__file__)),
"info.txt")) as entryFile:
entryDict = json.load(entryFile)
newEntry = sys.argv[1]
newValue = sys.argv[2]
confirmNew = input("Add \"{0}\" with \"{1}\" to the dictionary?"
"\ny or n\n".format(newEntry, newValue))
if confirmNew == "y":
entryDict[newEntry] = newValue
print("You have added {} to your dictionary".format(newEntry))
else:
print("You have not added a new entry")
entryString = json.dumps(entryDict)
with open(os.path.join(os.path.abspath(os.path.dirname(__file__)),
"info.txt"), "r+") as entryFile:
entryFile.write(entryString)
def update():
print("An entry with this name already exists.")
entryFile = open(os.path.join(os.path.abspath(os.path.dirname(__file__)),
"info.txt"), "r+")
entryDict = json.load(entryFile)
confirmUpdate = input("Update '{0}' with '{1}'?\n"
.format(sys.argv[1], sys.argv[2]))
if confirmUpdate == "y":
entryDict.update({str(sys.argv[1]): sys.argv[2]})
entryString = json.dumps(entryDict)
entryFile.truncate(0)
entryFile.write(entryString)
entryFile.close()
print("{} has been updated.".format(sys.argv[1]))
def main():
entryFile = open(os.path.join(os.path.abspath(os.path.dirname(__file__)),
"info.txt"))
entryDict = json.load(entryFile)
entryFile.close()
if len(sys.argv) < 2:
print('usage: python3 {} entry value - entry manager '
'\nentry: name of entry and its value to add to the dict.'
.format(sys.argv[0]))
sys.exit()
if len(sys.argv) == 3 and not sys.argv[1] in entryDict:
addNew()
sys.exit()
if len(sys.argv) == 3 and sys.argv[1] in entryDict:
update()
sys.exit()
if __name__ == "__main__":
main()
它按预期工作,直到我两次调用update()
函数。换句话说,只有当我python3 file.py entryName valueHere
两次时才会出现JSONDecodeError。两次,因为根据程序,如果info.txt字典中已经存在entryName,那么它应该更新该条目。
为什么update()
只能工作一次,但不能两次?
错误:raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
指向主要功能中的entryDict = json.load(entryFile)
我尝试了load/loads
,"r/w/a+"
的不同变体。似乎没什么用。我在做什么(主要)错了?
编辑:非常感谢任何关于通用脚本/编程的提示/技巧。
答案 0 :(得分:2)
问题在于,在调用file.truncate(0)
之后,您不会将新内容写入文件的开头。来自the docs:
截形(大小=无)
将流大小调整为给定大小(以字节为单位)(如果未指定大小,则调整当前位置)。 当前的流位置不是 更改。此调整大小可以扩展或减少当前文件大小。在 扩展的情况下,新文件区域的内容取决于 平台(在大多数系统上,附加字节为零填充)。新的 返回文件大小。
因此,在读取,截断并写入文件之后,文件的内容看起来会像这样(其中\x00
表示空字节):
\x00\x00\x00\x00\x00\x00\x00\x00{"key": "value"}
要解决此问题,请在entryFile.seek(0)
之后添加entryFile.truncate(0)
。