文件已关闭吗?

4

我经常看到这种代码:

filecontent = open(thefilename).read()

我想知道在这种情况下,由open创建的文件对象会发生什么:它会被隐式关闭,还是会保持在某个地方开启?

1个回答

12
我想知道在这种情况下,由open创建的文件对象会变成什么样子:它是否会被隐式关闭,还是会一直保持开启状态? 答案是:该文件对象会一直保持开启状态,直到垃圾收集器发现没有人可以再访问它并将其销毁时,才会被关闭。(Python语言对于垃圾收集的时间不做任何保证,除了当你无法再访问文件时,它肯定会在之后关闭。) 但是,在CPython中,一旦最后一个引用消失(除非它曾经参与循环),对象就会被销毁,所以在大多数情况下,文件将会在你从函数返回、给filecontent赋新值或使用del filecontent时立即关闭。但在其他Python实现中,则可能无法保证何时回收垃圾。因此,如果需要确保文件在适当的时间关闭,最好使用with语句。
with open(thefilename) as f:
    filecontent = f.read()

这保证了当with语句结束时,f.close()会被立即调用。

偶尔会有人建议将其变成一行代码,对此Guido总是回答类似于:“with open(thefilename) as f: filecontent = f.read()已经是一行代码了。虽然不太好看,但远比你建议的要好得多。”

但实际上,还有一个更好的答案:编写一个包装它的函数:

def read_whole_file(filename):
    with open(thefilename) as f:
        return f.read()

然后:

filecontent = read_whole_file(thefilename)

简洁、明了、易读……没有借口使用 "open 全部打开并让垃圾回收处理" 这种 hack。


1
总的来说,对象不一定被完全收集。在CPython中,如果一个__del__方法是循环引用的一部分,它将不会被调用-我不知道这是否会影响文件(我认为它们仍然会在解释器关闭时关闭),但对于我们自己的对象可能很重要。 - user395760
@delnan:显然,即使Python放弃文件句柄,任何现代操作系统都会在进程关闭时关闭它。因此,对于以读模式打开的文件,谁在乎它们是否关闭呢?但是对于以写模式打开的文件,情况就不同了,因为除非解释器明确关闭文件,否则文件可能不会被刷新。有关详细信息,请参见POSIX exit。(不确定Windows等效文档在哪里记录。) - abarnert
谁给我点了踩,能解释一下为什么吗? - abarnert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接