Python GC也会关闭文件吗?

时间:2018-03-27 12:34:35

标签: python file garbage-collection

考虑以下Python(2.x)代码:

for line in open('foo').readlines():
    print line.rstrip()

我认为由于打开的文件仍未被引用,因此必须自动关闭。我已经阅读了Python中的垃圾收集器,它释放了未使用对象分配的内存。 GC是否足以处理文件?

3 个答案:

答案 0 :(得分:4)

取自docs(python 3.6):

  

如果你没有使用with关键字,那么你应该调用f.close()来关闭文件并立即释放它使用的任何系统资源。如果您没有显式关闭文件, Python的垃圾收集器最终会破坏该对象并为您关闭打开的文件,但该文件可能会暂时保持打开状态。另一个风险是不同的Python实现将在不同的时间进行清理。

是的,该文件将自动关闭,但为了控制该过程,您应该自己动手或使用with声明:

with open('foo') as foo_file
    for line in foo_file.readlines():
        print line.rstrip()
一旦foo_file块结束

with将被删除

在python 2.7 docs中,措辞不同:

  

完成文件后,请调用f.close()将其关闭并释放   打开文件占用的任何系统资源。打电话后   f.close(),尝试使用文件对象将自动失败。

所以我假设你不应该依赖垃圾收集器为你自动关闭文件而只是手动/使用with

答案 1 :(得分:0)

这取决于您的操作,请查看此description how it works

一般情况下,我建议使用文件的上下文管理器:

with open("foo", "r") as f:
    for line in f.readlines():
    # ....

类似于(基本理解):

file_context_manager = open("foo", "r").__enter__()
for line in file_context_manager.readlines():
    # ....
file_context_manager.__exit__()

第一个版本更具可读性,with语句自动调用exit方法(加上context handling更多)。 当留下with语句的范围时,该文件将自动关闭。

答案 2 :(得分:0)

我经常在没有 open 的情况下使用 with,所以我进行了一个小测试。对于测试,我使用 Python 3.9,所以我不是在谈论早期版本,但至少对于 3.9,我们不需要 with 来关闭干净的文件。

bash

 inotifywait -m "testfile"

python3.9

 lines=[line for line in open("testfile")]
 sleep(5)
 for line in lines:
    print(line)

观察 inotifywait 窗口并运行 python 脚本。在睡眠之前,最终事件将是 CLOSE_NOWRITE,CLOSE,并且通过 python 脚本的运行不会有来自该文件的其他事件。