Python中文件对象忘记调用f.close()会出什么问题?Image.open()需要手动关闭吗?

要是忘用 f.close() 或 with open() as f 关闭对象,会出什么问题吗?

发现 PIL 的 Image 不用关闭方法吗? f = Image.open(img_file) 就没找到 f.close() 的关闭方法,不知道是为什么,求指点


Python中文件对象忘记调用f.close()会出什么问题?Image.open()需要手动关闭吗?
16 回复

问之前建议去查文档


文件不关,系统资源(比如文件描述符)会一直被占用。如果程序长时间运行或频繁打开文件,可能导致“Too many open files”错误,程序崩溃。

对于普通文件操作,用 with 语句是标准做法,它能确保文件被正确关闭,即使发生异常:

with open('file.txt', 'r') as f:
    data = f.read()
# 离开with块后,f会自动关闭

对于 Image.open(),Pillow库的Image对象本身不是文件句柄。它打开文件读取数据后,通常会立即关闭底层文件。所以一般不需要手动关。但如果你用 Image.open() 打开了文件,然后又去进行需要文件保持打开状态的低级操作,那得注意。通常的图片处理(resizesave等)不需要操心关闭。

总结:普通文件用 withImage.open() 一般不用管。

好像是因为没有关闭文件的话,系统会先缓存起来,然后慢慢写入文件,这样的话如果在写入途中断电会造成写入文件的不完整。

不关闭文件就一直打开在那里了,相关数据结构会占用内存,在进程退出之前会造成文件删不掉,所在文件系统无法 unmount。同时一个进程能打开的文件描述符有数量上限,打开大量文件后就会打不开新文件。
PIL 的 Image class 明明有 close() 方法啊
https://pillow.readthedocs.io/en/5.0.0/reference/Image.html#PIL.Image.Image.close

在 python 里不 close 跟在 C 里不 close 是一样,可能导致的问题包括不限于:
Windows 好像是自动加锁的,所以不能重复 open 咯
文件内容不能即时 flush 到磁盘直到进程结束

所以如果你线程比较多或者有可能变僵尸的话会造成一些很莫名其妙的错误。如果文件内容不大,能及时读到内存,读完就可以关了。Image 应该只管读,读完你还得手动关文件(关文件不是关图像)。

*nix 才是加锁的吧? Windows 的 CreateFile 可以指定 share mode。

不是句柄泄露或者文件占用吗

*nix 的特色之一不就是不主动加锁,要手动 fcntl/flock 吗。win 我不太了解,但是要是搬出 CreateFile 这种高大全 API 也就谈不上什么自动不自动了。刚刚求证了一下 MSDN,有讲到 Files opened by fopen_s and _wfopen_s are not sharable,我指的所谓自动是指调用一些比较通用、标准的函数时的行为。

我怎么记得文件变量回收后会自动关闭

Linux 默认是 shared mode.

以前国外论坛看过一个解释,如果是原版的 py 引用计数垃圾回收,变量用完后就回收,文件自然也就关闭了,所以不 close 也没什么大问题。如果是别的版本的 py 垃圾回收话关闭时间会延长,就会有问题。所以建议还是加上

If you don ’ t use “ with ”, when does Python close files? The answer is: It depends.

http://blog.lerner.co.il/dont-use-python-close-files-answer-depends/

GC 执行时间是不确定的,可能长时间不回收

找不到方法的时候就用 with 啊 这种类型自动 close。。。

Image 里面有__exit__,退出时调用了 close

回到顶部