问题:明确关闭文件重要吗?
在Python中,如果您不调用即可打开文件close()
,或者不使用try
– finally
或“ with
”语句而关闭文件,这是问题吗?还是依靠Python垃圾回收来关闭所有文件作为一种编码实践就足够了?例如,如果这样做:
for line in open("filename"):
# ... do stuff ...
…这是一个问题,因为文件永远无法关闭,并且可能发生阻止文件关闭的异常吗?还是for
由于文件超出范围而肯定会在声明结束时将其关闭?
回答 0
在您的示例中,不能保证在解释器退出之前关闭文件。在当前版本的CPython中,该文件将在for循环结束时关闭,因为CPython使用引用计数作为其主要的垃圾收集机制,但这是实现细节,而不是语言的功能。不能保证其他Python实现会以这种方式工作。例如,IronPython,PyPy和Jython不使用引用计数,因此不会在循环结束时关闭文件。
依靠CPython的垃圾回收实现是一个坏习惯,因为它使您的代码可移植性降低。如果使用CPython,则可能不会发生资源泄漏,但是,如果切换到不使用引用计数的Python实现,则需要遍历所有代码并确保正确关闭了所有文件。
作为示例,请使用:
with open("filename") as f:
for line in f:
# ... do stuff ...
回答 1
有些Python在不再被引用时会自动关闭文件,而其他Python不会,并且在Python解释器退出时由O / S来关闭文件。
即使对于将为您关闭文件的Python,也无法保证时间:可能是立即执行,也可能是秒/分钟/小时/天之后。
因此,尽管您使用的Python可能不会遇到问题,但绝对不要将文件保持打开状态。实际上,在cpython 3中,您现在会得到警告,如果您不这样做,系统必须为您关闭文件。
道德:自己清理。:)
回答 2
尽管在这种特殊情况下使用这种构造是相当安全的,但仍需注意一些概括这种做法的注意事项:
- 运行可能会用完文件描述符,尽管这不太可能,想象一下找到这样的错误
- 您可能无法在某些系统上删除该文件,例如win32
- 如果您运行的不是CPython,则不知道何时关闭文件
- 如果以写或读写模式打开文件,则不知道何时刷新数据
回答 3
该文件确实会收集垃圾,因此已关闭。GC将确定关闭的时间,而不是您。显然,这不是推荐的做法,因为如果您没有在使用完文件后立即关闭文件,则可能会达到打开文件句柄的限制。如果在您的那个for
循环中打开更多文件而让它们挥之不去怎么办?
回答 4
嗨,当您要在同一python脚本中使用文件描述符时,关闭文件描述符非常重要。经过很长时间的调试之后,我今天才意识到。原因是仅在关闭文件描述符后,内容才会被编辑/删除/保存,并且对文件的更改也会受到影响!
因此,假设您遇到的情况是将内容写入新文件,然后不关闭fd而在另一个读取其内容的shell命令中使用该文件(而非fd)。在这种情况下,您将无法按预期获得shell命令的内容,并且如果尝试调试,将很难找到该错误。您也可以在我的博客条目http://magnificentzps.blogspot.in/2014/04/importance-of-closing-file-descriptor.html中阅读更多内容
回答 5
在I / O过程中,数据被缓冲:这意味着在将数据写入文件之前将其保留在一个临时位置。
Python不会刷新缓冲区(即,将数据写入文件),直到确定完成写入为止。一种方法是关闭文件。
如果您在不关闭的情况下写入文件,则数据将不会写入目标文件。