明确关闭文件重要吗?

时间:2011-09-13 00:27:08

标签: python file garbage-collection

在Python中,如果您在未调用close()的情况下打开文件,或关闭文件但未使用try - finally或“with”语句,则这个问题?或者它是否足以作为编码实践依赖Python垃圾收集来关闭所有文件?例如,如果有人这样做:

for line in open("filename"):
    # ... do stuff ...

...这是一个问题,因为文件永远不会被关闭,并且可能发生阻止它被关闭的异常?或者它肯定会在for语句结束时关闭,因为文件超出了范围?

6 个答案:

答案 0 :(得分:116)

在您的示例中,不保证在解释器退出之前关闭文件。在当前版本的CPython中,文件将在for循环结束时关闭,因为CPython使用引用计数作为其主要垃圾收集机制,但这是一个实现细节,而不是该语言的一个特性。 Python的其他实现不能保证以这种方式工作。例如,IronPython,PyPy和Jython不使用引用计数,因此不会在循环结束时关闭文件。

依赖CPython的垃圾收集实现是不好的做法,因为它会降低你的代码的可移植性。如果使用CPython,可能没有资源泄漏,但如果您切换到不使用引用计数的Python实现,则需要检查所有代码并确保所有文件都正确关闭。

对于您的示例:

with open("filename") as f:
     for line in f:
        # ... do stuff ...

答案 1 :(得分:21)

一些Pythons会在不再引用文件时自动关闭文件,而其他Pythons则不会在Python解释器退出时由O / S关闭文件。

即使对于会为你关闭文件的Pythons,也不能保证时间:它可以是立即的,也可以是秒/分钟/小时/天。

因此,虽然您可能不会遇到使用Python的问题,但将文件保持打开绝对不是一个好习惯。事实上,在cpython 3中,您现在会收到警告,如果您不这样做,系统必须为您关闭文件。

道德:自己清理。 :)

答案 2 :(得分:9)

虽然在这种特殊情况下使用这种结构是相当安全的,但是有一些注意事项可以推广这种做法:

  • 运行可能会耗尽文件描述符,尽管不太可能,想象一下这样的错误
  • 您可能无法在某些系统上删除所述文件,例如的win32
  • 如果您运行CPython以外的任何内容,则不知道文件何时关闭
  • 如果以写入或读写模式打开文件,则不知道何时刷新数据

答案 3 :(得分:3)

该文件确实被垃圾收集,因此关闭。 GC确定何时关闭,而不是您。显然,这不是推荐的做法,因为如果在完成使用后不立即关闭文件,可能会遇到打开文件句柄限制。如果在你的for循环中,你打开更多文件并让它们挥之不去?

答案 4 :(得分:3)

嗨,当您要在同一个python脚本中使用它的内容时,关闭文件描述符非常重要。我今天自己意识到经过这么长时间的调试。原因是只有在关闭文件描述符并且更改受文件影响后才会编辑/删除/保存内容!

因此,假设您有将内容写入新文件的情况,然后在不关闭fd的情况下,您正在另一个读取其内容的shell命令中使用该文件(而不是fd)。在这种情况下,您不会按预期获得shell命令的内容,如果您尝试调试,则无法轻松找到错误。您还可以在我的博客文章http://magnificentzps.blogspot.in/2014/04/importance-of-closing-file-descriptor.html

中阅读更多内容

答案 5 :(得分:1)

在I / O进程中,数据被缓冲:这意味着在将数据写入文件之前将其保留在一个临时位置。

Python不会刷新缓冲区(即,将数据写入文件),直到确定完成写入为止。一种方法是关闭文件。

如果不关闭就写入文件,数据将不会写入目标文件。