明确关闭文件重要吗?

use*_*702 141 python garbage-collection file

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

for line in open("filename"):
    # ... do stuff ...
Run Code Online (Sandbox Code Playgroud)

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

Pet*_*ham 121

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

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

对于您的示例使用:

with open("filename") as f:
     for line in f:
        # ... do stuff ...
Run Code Online (Sandbox Code Playgroud)

  • @Rohan是的,这就是`with`语句提供的小魔法,但当然对于这个魔法来说,对象必须有特殊的方法`__enter__`和`__exit__`,在后者中对象做`close`以及需要在`with`语句结束时完成的任何其他清理工作...... (18认同)
  • 使用`with open()as f`会在文件完成后自动关闭文件吗? (6认同)
  • 仅供参考:这个答案只解释了“什么时候关闭”,但没有解释“如果它保持打开状态会怎样”。对于后者,请阅读“如果文件保持打开状态会怎样?” 参与这个答案(http://askubuntu.com/questions/701491/is-closure-a-file-after-have-opened-it-with-open-required-in-python) (2认同)

Eth*_*man 22

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

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

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

道德:自己清理.:)

  • 文件在CPython中不再引用时会关闭,但这不是语言功能.如果它是你可以很乐意依靠它. (8认同)

Dim*_*nek 9

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

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


Nam*_*yen 3

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