在Python文件对象上使用迭代器时,close()必要吗?
这样做是不是不太好,就是不明确处理一个文件对象,也不调用它的 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 个回答
很奇怪,在这个讨论系统资源释放重要性的主题中,居然没有人提到一个我认为更重要的原因,那就是为了能再次打开文件,所以我们应该确定性地关闭文件。
当然,有些情况下关闭文件并不重要。如果一个文件对象超出了作用域或者被删除了,底层的文件会被关闭。(具体关闭的时间取决于你使用的Python版本。)通常来说,这样就足够了——前提是你确切知道文件变量什么时候会超出作用域,并且前提是你不在乎文件是否被确定性地关闭。
但是,既然有了with
语句,为什么还要为这种分析烦恼呢?
其实,当文件被“垃圾回收”时,它会被关闭。你可以查看这个问题,了解更多关于这个过程的内容。
不过,还是建议你使用 try
/finally
结构或者 with
语句来处理文件。如果在使用文件的方法时发生了错误,错误信息会被记录下来,直到你手动清除或者发生另一个错误。
所以,依赖垃圾回收来帮你关闭文件并不是个好主意。
另外,如果你对文件进行了写入,直到文件被关闭或者刷新之前,你无法保证这些更改会被保存。
在处理文件时,关闭文件是绝对必要的,随便留着打开的文件句柄可不是个好主意。虽然最终文件对象会被垃圾回收机制关闭,但你不知道具体什么时候会发生。在这段时间里,你会浪费系统资源,因为你还在占用那些不再需要的文件句柄。
如果你使用的是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