Python 文件对象忘了 f.close() 会出什么问题? f = Image.open() 不用 close 方法吗?

2018-01-05 22:15:49 +08:00
 miniyao

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

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

9064 次点击
所在节点    Python
15 条回复
TimePPT
2018-01-05 22:34:28 +08:00
问之前建议去查文档
ech0x
2018-01-05 22:34:45 +08:00
好像是因为没有关闭文件的话,系统会先缓存起来,然后慢慢写入文件,这样的话如果在写入途中断电会造成写入文件的不完整。
billlee
2018-01-05 22:36:01 +08:00
不关闭文件就一直打开在那里了,相关数据结构会占用内存,在进程退出之前会造成文件删不掉,所在文件系统无法 unmount。同时一个进程能打开的文件描述符有数量上限,打开大量文件后就会打不开新文件。
PIL 的 Image class 明明有 close() 方法啊
https://pillow.readthedocs.io/en/5.0.0/reference/Image.html#PIL.Image.Image.close
shihira
2018-01-05 22:39:35 +08:00
在 python 里不 close 跟在 C 里不 close 是一样,可能导致的问题包括不限于:
Windows 好像是自动加锁的,所以不能重复 open 咯
文件内容不能即时 flush 到磁盘直到进程结束

所以如果你线程比较多或者有可能变僵尸的话会造成一些很莫名其妙的错误。如果文件内容不大,能及时读到内存,读完就可以关了。Image 应该只管读,读完你还得手动关文件(关文件不是关图像)。
ysc3839
2018-01-06 01:37:09 +08:00
@shihira *nix 才是加锁的吧? Windows 的 CreateFile 可以指定 share mode。
Arnie97
2018-01-06 02:10:39 +08:00
crab
2018-01-06 03:46:52 +08:00
@shihira 不是句柄泄露或者文件占用吗
shihira
2018-01-06 04:24:59 +08:00
@ysc3839 *nix 的特色之一不就是不主动加锁,要手动 fcntl/flock 吗。win 我不太了解,但是要是搬出 CreateFile 这种高大全 API 也就谈不上什么自动不自动了。刚刚求证了一下 MSDN,有讲到 Files opened by fopen_s and _wfopen_s are not sharable,我指的所谓自动是指调用一些比较通用、标准的函数时的行为。
binux
2018-01-06 04:27:17 +08:00
我怎么记得文件变量回收后会自动关闭
jimzhong
2018-01-06 04:57:48 +08:00
@ysc3839 Linux 默认是 shared mode.
doubleflower
2018-01-06 07:58:06 +08:00
以前国外论坛看过一个解释,如果是原版的 py 引用计数垃圾回收,变量用完后就回收,文件自然也就关闭了,所以不 close 也没什么大问题。如果是别的版本的 py 垃圾回收话关闭时间会延长,就会有问题。所以建议还是加上
mimzy
2018-01-06 13:25:12 +08:00
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/
guyskk0x0
2018-01-06 14:12:55 +08:00
@binux GC 执行时间是不确定的,可能长时间不回收
rffan
2018-01-06 15:43:17 +08:00
找不到方法的时候就用 with 啊 这种类型自动 close。。。
ml071987
2018-01-06 16:05:57 +08:00
Image 里面有__exit__,退出时调用了 close

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/420477

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX