Should json.load() or json.dump() be used with an open() context manager?
例如,假设我们正在检查一个
1 2 3 | { "background_color":"red" } |
然后,我们使用python json模块读取/修改/写回首选项。以下两个示例的功能相同,除了一个使用
1 2 3 4 5 6 7 8 9 10 11 12 13 | import json # Load the user preferences with open('preferences.json') as prefs_file: prefs = json.load(prefs_file) print(prefs['background_color']) # Prints 'red' # Change the user's background_color preference to blue prefs['background_color'] = 'blue' # Save the user preferences with open('preferences.json', 'w') as prefs_file: json.dump(prefs, prefs_file) |
1 2 3 4 5 6 7 8 9 10 11 | import json # Load the user preferences prefs = json.load(open('preferences.json')) print(prefs['background_color']) # Prints 'red' # Change the user's background_color preference to blue prefs['background_color'] = 'blue' # Save the user preferences prefs = json.dump(prefs, open('preferences.json', 'w')) |
对于正常的文件读/写,我总是使用上下文管理器并处理上下文管理器内的所有逻辑。但在本例中,文件的使用时间刚好足以填充dict或将dict写入文件。所以不使用上下文管理器的例子对我来说似乎更清楚。我担心,由于这些文件是以"匿名"方式打开的,所以没有什么可以调用
我开始寻找JSON模块的源代码,但是在找到它并搜索"dump"和"load"之后,我不知道接下来要检查什么。我对C还不够精通,无法理解里面发生了什么。
这两者都是安全的,但是使用上下文管理器的版本是更好的实践。
请记住,当您的程序退出时,所有写操作都将被刷新。也就是说,上下文管理器会导致立即关闭和刷新,而不是在垃圾收集上,也不是在退出时。因此,它更加明确,即使在程序末尾添加了更多(可能是长时间运行的)代码,也会确保事情立即生效。
也就是说,考虑一下让你的文章真正具有原子性。这里仍然有一个窗口,文件已被打开以供输出,但没有新的内容被刷新;如果电源被猛拉,或者您有一个sigkill,或者读卡器试图将文件的内容拉入该窗口,您将丢失数据。请看用python编写原子文件;就我个人而言,我赞成@vog的建议,使用一个专门构建的库,它了解各种平台的习惯用法和最佳实践。