在Python文件对象上使用迭代器时,close()必要吗?

53 投票
8 回答
66119 浏览
提问于 2025-04-15 16:36

这样做是不是不太好,就是明确处理一个文件对象,也不调用它的 close() 方法?

for line in open('hello.txt'):
    print line

注意 - 这是针对还没有 with 语句的 Python 版本。

我问这个是因为 Python 的文档似乎推荐这样做 :-

f = open("hello.txt")
try:
    for line in f:
        print line
finally:
    f.close()

这看起来比必要的要啰嗦一些。

8 个回答

13

很奇怪,在这个讨论系统资源释放重要性的主题中,居然没有人提到一个我认为更重要的原因,那就是为了能再次打开文件,所以我们应该确定性地关闭文件。

当然,有些情况下关闭文件并不重要。如果一个文件对象超出了作用域或者被删除了,底层的文件会被关闭。(具体关闭的时间取决于你使用的Python版本。)通常来说,这样就足够了——前提是你确切知道文件变量什么时候会超出作用域,并且前提是你不在乎文件是否被确定性地关闭。

但是,既然有了with语句,为什么还要为这种分析烦恼呢?

21

其实,当文件被“垃圾回收”时,它会被关闭。你可以查看这个问题,了解更多关于这个过程的内容。

不过,还是建议你使用 try/finally 结构或者 with 语句来处理文件。如果在使用文件的方法时发生了错误,错误信息会被记录下来,直到你手动清除或者发生另一个错误。

所以,依赖垃圾回收来帮你关闭文件并不是个好主意。

另外,如果你对文件进行了写入,直到文件被关闭或者刷新之前,你无法保证这些更改会被保存。

86

在处理文件时,关闭文件是绝对必要的,随便留着打开的文件句柄可不是个好主意。虽然最终文件对象会被垃圾回收机制关闭,但你不知道具体什么时候会发生。在这段时间里,你会浪费系统资源,因为你还在占用那些不再需要的文件句柄。

如果你使用的是Python 2.5及以上版本,可以通过with语句自动调用close()

from __future__ import with_statement # Only needed in Python 2.5
with open("hello.txt") as f:
    for line in f:
        print line

这和你写的代码效果是一样的:

f = open("hello.txt")
try:
    for line in f:
        print line
finally:
    f.close()

with语句是对一种常见于C++的编程习惯的直接支持,这种习惯叫做资源获取即初始化。它可以安全地使用和清理各种资源,比如确保数据库连接总是被关闭,或者锁总是被释放,像下面这样。

mylock = threading.Lock()
with mylock:
    pass # do some thread safe stuff

撰写回答