Python垃圾回收(GC)是否会自动关闭未引用文件?
Python 2.x中未引用文件的自动关闭问题
咱们先聊聊你贴的这段代码:for line in open('foo').readlines(): print line.rstrip()。这里open('foo')返回的文件对象没被赋值给任何变量,相当于没有引用指向它,你关心的是Python的GC能不能自动帮你关掉这个文件,对吧?
答案是:大多数情况下GC会触发文件关闭,但绝对不能依赖这个机制。
为什么说“大多数情况下”?
Python的文件对象在被垃圾回收器标记为“不可达”(也就是没有任何引用指向它)时,其内置的__del__方法会被调用,而这个方法里包含了关闭文件的逻辑。所以从理论上来说,GC确实会帮你释放文件资源。
但为什么不能依赖它?
这里有几个关键的坑:
- GC运行时机不确定:Python 2.x的分代GC只有在内存占用达到特定阈值时才会触发,如果你的程序内存充足,这个文件对象可能会在很长时间内保持打开状态,导致系统文件描述符被占用,甚至出现同一文件无法再次打开的权限问题。
- 异常场景下可能失效:如果程序中途崩溃或者被强制终止,GC根本没机会运行,文件就会一直处于打开状态,这可能导致数据丢失或文件损坏。
- 跨平台行为不一致:不同操作系统对未关闭文件的处理逻辑可能有差异,依赖GC的话会让你的代码兼容性变差。
正确的做法是什么?
强烈推荐使用上下文管理器(with语句),Python 2.5及以上版本都支持:
with open('foo') as f: for line in f: print line.rstrip()
with语句会在代码块执行结束(不管是正常结束还是抛出异常)时自动调用文件对象的close()方法,彻底避免资源泄漏问题。另外提一句,原代码里的readlines()其实没必要,直接迭代文件对象for line in f更高效,它不会一次性把整个文件读到内存里,处理大文件时优势明显。
内容的提问来源于stack exchange,提问作者Vladimir Zolotykh
相关产品推荐
相关产品推荐

