json.load()或json.dump()应该与open()上下文管理器一起使用吗?

时间:2018-03-21 15:50:53

标签: python json file contextmanager

例如,假设我们正在检查带有

内容的preferences.json文件 的 preferences.json
{
    "background_color": "red"
}

然后我们使用Python json module读取/修改/写回首选项。以下两个示例的功能相同,只是一个使用open()上下文管理器而另一个不使用。

change_pref_with_CM.py
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)
change_pref_without_CM.py
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写入文件。因此,不使用上下文管理器的示例对我来说似乎更清晰。我担心,因为文件是“匿名”打开的,所以没有任何东西可以调用close(),我不知道json模块是否在内部处理上下文管理器或者我是否只是{{3} }。我确定使用上下文管理器以防万一是安全的方法,但同时我想知道json模块如何处理文件描述符(leaking file descriptors

我去寻找json模块的源代码但是在or is it file objects?之后搜索“dump”和“load”并找不到任何东西我不知道接下来要检查什么。我对C的熟悉程度不足以了解那里发生了什么。

1 个答案:

答案 0 :(得分:2)

其中任何一个都是安全的,但带有上下文管理器的版本是更好的做法。

请记住,当程序退出时,所有写入都会被刷新。也就是说,上下文管理器会导致关闭并刷新立即,而不是垃圾回收,而不是退出。因此,它更明确,并且即使在程序结束时添加了更多(可能是长期运行的)代码,也会确保事情立即生效。

那就是说,考虑让你的写作真正成为原子。

这里还有一个窗口,文件已打开输出,但没有新内容刷入其中;如果电源被拉扯,或者您有SIGKILL,或者读者只是试图在该窗口内拉入文件内容,那么您将丢失数据。见atomic writing to file with Python;就个人而言,我赞成建议by @vog使用一个专门建立的图书馆,该图书馆了解各种平台'习语和最佳实践。