python - 文件是否关闭?

标签 python file python-3.x

<分区>

我经常看到这种代码:

filecontent = open(thefilename).read()

我想知道在这种情况下 open 创建的文件对象是什么:它是隐式关闭的,还是在某处保持打开状态?

最佳答案

I wonder what becomes the file object created by open in this situation: is it implicitly closed, or does it stay open somewhere ?

它一直保持打开状态,直到垃圾收集器发现没有人可以再访问它并销毁它,此时它被析构函数关闭。

Python 语言不保证什么时候会发生(当然,除非是在您无法再访问它之后)。

但是,CPython 实现(您可能正在使用它,因为截至 2013 年 5 月,它是唯一可用的 3.x 实现)使用引用计数(加上循环检测器)进行垃圾收集,这意味着一旦最后一个引用消失了(除非它在某个时候参与了一个循环),对象被销毁。

因此,在 CPython 中,在大多数情况下,一旦您从函数返回,将新值分配给 filecontentdel filecontent,文件就会立即关闭.很多快速而肮脏的代码都依赖于此。

但 Jython 和 IronPython 依赖于 Java/.NET 垃圾收集器,它以复杂而奇特的方式定期检查垃圾,而不是动态跟踪,因此无法保证何时收集任何东西。 PyPy 有多个选项,具体取决于它的配置方式。

而且,即使在 CPython 中,在没有可见 引用之后,垃圾也有可能留在周围,因为,例如,您在调试器中运行它并最终得到一些不可见 引用文献。或者,如果文件涉及引用循环,它可能永远不会关闭。

所以,除了快速和肮脏的代码之外,你不应该在任何地方依赖这种行为。基本上,如果文件在您的程序完成之前保持打开状态是可以接受的,那很好。否则,不要这样做。

正确的方法是使用 with 语句:

with open(thefilename) as f:
    filecontent = f.read()

这保证 f.close()with 语句完成后立即被调用。

人们经常会建议一种将其变成单行代码的方法,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)

干净、简洁、可读……没有任何借口可以“打开”,让 GC 将它们分类出来。

关于python - 文件是否关闭?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16405926/

相关文章:

python - 在Python线程内运行子进程实时读取输出

python - ndb 异步 "yield next"消费 get_multi 异步

python - 访问 dask 集群中分散数据的成本

c++ - 读取文件多数据类型 (c++)

ruby - 创建大文件的最快方法?

python-3.x - 在 Python 中使用 kwargs 添加参数

python - 在 Python 中将字符串格式化为恒定长度

c - 如何知道文件是否正在被复制?

Python for 循环操作列表并删除曾经使用过的元素

python-3.x - 尝试从 django 中的子模板加载 css 样式表