明确closures文件重要吗?

在Python中,如果你打开一个文件而不调用close() ,或者closures文件,而不是使用tryfinally或者“ with ”语句,这是一个问题吗? 还是仅仅依靠Python的垃圾收集来closures所有文件就足够了? 例如,如果这样做:

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

…这是一个问题,因为该文件永远不能closures,并可能会发生exception,防止它被closures? 或者for因为文件超出范围,它会在for语句结束时一定closures吗?

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

依靠CPython的垃圾收集实现是一个不好的做法,因为它使得你的代码更加便于移植。 如果您使用CPython,则可能没有资源泄漏,但是如果您切换到不使用引用计数的Python实现,则需要检查所有代码,并确保所有文件都已正确closures。

对于你的例子使用:

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

有些python会在不再被引用时自动closures文件,有些则不会,当Python解释器退出时,会自动closures文件。

即使是为您closures文件的Pythons,时间也不能保证:时间可能会立即,也可能是秒/分钟/小时/天之后。

所以,虽然你可能不会遇到你正在使用的Python的问题,但是打开文件绝对不是好的做法。 事实上,在cpython 3中,你现在会得到警告,如果你没有这样做,系统必须closures文件。

道德:自己清理。 🙂

尽pipe在这种情况下使用这样的构造是相当安全的,但是对于这种实践的总结还有一些注意事项:

  • 运行可能会用尽文件描述符,尽pipe不太可能,想象一下find这样的错误
  • 您可能无法删除某些系统上的文件,例如win32
  • 如果您运行的不是CPython,则不知道文件什么时候closures
  • 如果以写或读写模式打开文件,则不知道数据何时被刷新

嗨在打算在同一个python脚本中使用它的内容时,closures文件描述符是非常重要的。 我今天自己实现了这么长时间的debugging。 原因是内容将被编辑/删除/保存只有当你closures你的文件描述符和变化影响文件!

所以假设你有写内容到一个新文件的情况,然后在没有closuresfd的情况下,在另外一个读取其内容的shell命令中使用该文件(而不是fd)。 在这种情况下,你不会像预期的那样得到你的shell命令的内容,如果你尝试debugging,你不能轻易findbug。 你也可以阅读我的博客http://magnificentzps.blogspot.in/2014/04/importance-of-closing-file-descriptor.html

该文件确实收集垃圾,因此closures。 GC决定何时closures,而不是你。 显然,这不是一个推荐的做法,因为如果您在完成使用后不立即closures文件,则可能会打开文件句柄限制。 如果在你的循环中,你打开更多的文件,并留下他们挥之不去?