在Python文件obj上使用迭代器时需要close()

2024-05-17 18:30:04 发布

您现在位置:Python中文网/ 问答频道 /正文

执行以下操作而不显式处理文件对象并调用其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()

似乎比必要的更冗长。


Tags: 文件对象方法in文档版本txthello
3条回答

奇怪的是,对于这个主题中关于释放系统资源的重要性的所有讨论,在我看来,没有人提到一个明显更重要的原因来确定地关闭一个文件:以便可以再次打开它。

当然,有些情况下这并不重要。如果文件对象超出范围或被删除,则基础文件将被关闭。(何时关闭取决于您正在使用的Python的特定实现)这通常是足够好的-如果您确切地知道文件变量何时将超出范围,并且如果您知道您不关心文件是否确定性地关闭。

但是,当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()

^ {}语句是C++中常用的Resource Acquisition Is Initialization习惯用法的直接语言支持。它允许安全地使用和清理各种资源,例如,它可以用于始终确保关闭数据库连接或始终像下面这样释放锁。

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

实际上,文件在garbage collected时将被关闭。请参阅this question了解有关如何工作的更多信息。

但仍然建议您使用try/finally块或with语句。如果在使用某个文件对象的方法时出现异常,则引用将存储在回溯(作为全局变量存储)中,直到您清除它或发生另一个异常。

因此,依赖垃圾收集为您关闭文件是不好的。

此外,如果已写入文件,则在关闭或刷新文件之前,无法保证将更改保存到该文件。

相关问题 更多 >