<p>要添加到<a href="https://stackoverflow.com/a/30092299/908494">James Mills' answer</a>,如果需要了解没有看到任何错误的具体原因:</p>
<p>Python定义当一个文件被垃圾回收时,它将自动关闭。但是Python将如何处理垃圾收集留给了实现。您可能正在使用的CPython实现使用引用计数:一旦对对象的最后一个引用消失,它就会立即被收集。因此,所有这些都将在CPython中起作用:</p>
<pre><code>def spam():
for i in range(100000):
open('spam.txt') # collected at end of statement
def eggs():
for i in range(100000):
f = open('eggs.txt') # collected next loop, when f is reassigned
def beans():
def toast():
f = open('toast.txt') # collected when toast exits
for i in range(100000):
toast()
</code></pre>
<hr/>
<p>但是许多其他实现(包括其他三大实现pypyy、Jython和IronPython)使用更智能的垃圾收集器,可以动态地检测垃圾,而不必跟踪所有引用。这使得它们更高效,更擅长线程处理等,但这意味着当一个对象被收集时,它是不确定的。所以同样的代码行不通。或者,更糟的是,它将在你的60个测试中起作用,然后在你为你的投资者做演示时就失败了。在</p>
<p>如果您需要PyPy的速度或IronPython的.NET集成,但如果不重写所有代码就不能拥有它,那就太可惜了。或者,如果其他人想使用您的代码,但需要它在Jython中工作,而不得不另寻他处。在</p>
<hr/>
<p>同时,即使在CPython中,解释器也不会在关闭时收集所有垃圾。(它越来越好,但即使在3.4版本中也不完美)所以在某些情况下,你需要依靠操作系统来关闭你的文件。操作系统通常会在刷新时刷新它们,但如果你在守护进程线程中打开了它们,或者你用<code>os._exit</code>退出,或者出现错误,则可能不会。(当然,如果你被电源线绊倒而退出,当然也不会。)</p>
<hr/>
<p>最后,即使是CPython(我想是从3.3开始)也有专门的代码来生成警告,如果你让你的文件被垃圾回收而不是关闭它们。这些警告在默认情况下是关闭的,但是人们经常建议打开它们,总有一天它可能会发生。在</p>