Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 文件关闭了吗?_Python_File_Python 3.x - Fatal编程技术网

Python 文件关闭了吗?

Python 文件关闭了吗?,python,file,python-3.x,Python,File,Python 3.x,我经常看到这种代码: filecontent = open(thefilename).read() 我想知道在这种情况下,open创建的文件对象会变成什么:它是隐式关闭的,还是在某个地方保持打开状态 我想知道在这种情况下open创建的文件对象会变成什么:它是隐式关闭的,还是在某个地方保持打开状态 它一直保持打开状态,直到垃圾收集器发现没有人可以再访问它并将其销毁,此时它被析构函数关闭 Python语言不保证何时会发生这种情况(当然,除了在您不能再访问它之后) 然而,CPython实现(您可能正

我经常看到这种代码:

filecontent = open(thefilename).read()
我想知道在这种情况下,
open
创建的文件对象会变成什么:它是隐式关闭的,还是在某个地方保持打开状态

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

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

Python语言不保证何时会发生这种情况(当然,除了在您不能再访问它之后)

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

因此,在CPython中,在大多数情况下,只要您从函数返回,为
filecontent
delfilecontent
指定一个新值,文件就会关闭。很多快速脏代码都依赖于此

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

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

因此,除了quick&dirty代码之外,您不应该在任何事情中依赖这种行为。基本上,如果文件在程序完成之前保持打开状态是可以接受的,则可以。否则,不要这样做

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

with open(thefilename) as f:
    filecontent = f.read()
这保证了
f.close()
语句完成后会立即调用
with
语句

经常有人建议将其转换为一行程序,Guido总是这样回答,“
将open(thefilename)作为f:filecontent=f.read()
已经是一行程序了。这有点糟糕,但远没有你建议的那么糟糕。”

但实际上,还有一个更好的答案:编写一个封装它的函数:

def read_whole_file(filename):
    with open(thefilename) as f:
        return f.read()
然后:

filecontent = read_whole_file(thefilename)

干净、简洁、易读……没有理由“打开所有对象并让GC对其进行排序”黑客攻击。

一般来说,对象根本不需要收集。在CPython中,如果是引用周期的一部分,则不会调用
\uuu del\uuu
方法-我不知道这是否会影响文件(我认为它们在解释器关闭时仍然关闭),但这可能会影响我们自己的对象。谢谢,响应非常好@delnan:显然,即使Python放弃了文件句柄,任何现代操作系统都会在进程关闭时关闭它。所以,对于处于读取模式的文件,谁会在乎它们是否已关闭,对吗?但是对于处于写模式的文件,情况就不同了,因为除非解释器显式关闭文件,否则文件可能不会被刷新。有关详细信息,请参见POSIX。(不知道Windows的等价物在哪里被记录。)谁投了反对票,请解释一下原因?