32

以下语法是否关闭文件:

lines = [line.strip() for line in open('/somefile/somewhere')]

如果你能证明它是如何做或不做的,那就加分……

蒂亚!

4

5 回答 5

33

它应该关闭文件,是的,尽管它何时关闭取决于实现。原因是列表理解结束后没有对打开文件的引用,所以它将被垃圾收集,然后关闭文件。

在 CPython(来自 python.org 的常规解释器版本)中,它会立即发生,因为它的垃圾收集器通过引用计数工作。在另一个解释器中,例如 Jython 或 Iron Python,可能会有延迟。

如果您想确保您的文件被关闭,最好使用以下with语句:

with open("file.txt") as file:
    lines = [line.strip() for line in file]

结束with后,文件将被关闭。即使在其中引发异常也是如此。

于 2013-09-17T03:37:08.003 回答
15

应该这样做

with open('/somefile/somewhere') as f:
    lines = [line.strip() for line in f]

在 CPython 中,该文件应立即关闭,因为没有对它的引用,但Python 语言不保证这一点

在 Jython 中,在垃圾收集器运行之前不会关闭文件

于 2013-09-17T03:36:53.877 回答
4

它不会。上下文管理器可用于自动关闭它。例如:

with open('/somefile/somewhere') as handle:
    lines = [line.strip() for line in handle]
于 2013-09-17T03:37:17.533 回答
3

这可以使用more_itertools1读取和关闭列表理解中的文件:

import more_itertools as mit

lines = [line.strip() for line in mit.with_iter(open("/somefile/somewhere"))]

注意more_itertools是第三方包。通过安装pip install more_itertools

另请参阅文档以获取有关more_itertools.with_iter.

于 2017-08-29T01:42:46.100 回答
2

是的,因为“打开”不会将文件句柄绑定到任何对象,一旦列表理解完成,它将在超出范围时关闭:

#!/usr/bin/env python3
import psutil

print('before anything, open files: ', end='')
print(psutil.Process().open_files())
f = open('/etc/resolv.conf')
print('after opening resolv.conf, open files: ', end='')
print(psutil.Process().open_files())
f.close()
print('after closing resolv.conf, open files: ', end='')
print(psutil.Process().open_files())
print('reading /etc/services via a list comprehension')
services = [ line.strip() for line in open('/etc/services') ]
print('number of items in services: ', end='')
print(len(services))
print('after reading /etc/services through list comp, open files: ', end='')
print(psutil.Process().open_files())
于 2017-11-06T14:43:43.680 回答