注意: 我知道
with open('f1') as f1, open('f2') as f2:
...
语法。 这是一个不同的问题。
给定一个字符串列表
file_names
是否有一种方法使用
with
/
as
使用单行打开其中的每个文件名。 诸如:
with [open(fn) for fn in file_names] as files:
# use the list of files
之类的东西当然不起作用,因为它尝试在列表上使用上下文管理器。 列表的长度直到运行时才知道
Python 中没有直接的方法可以使用单个
with
语句打开文件列表。这是因为
with
语句旨在处理单个上下文管理器或使用逗号分隔的多个上下文管理器,并且它需要在编译时知道上下文管理器的数量。
但是,可以使用循环和
contextlib.ExitStack
来实现类似的结果。
ExitStack
允许输入多个上下文管理器并确保在退出
with
块时正确关闭它们,而不管在处理文件期间是否发生异常。
以下是如何使用
ExitStack
打开文件列表的方法:
from contextlib import ExitStack
file_names = ['file1.txt', 'file2.txt', 'file3.txt']
with ExitStack() as stack:
files = [stack.enter_context(open(fn)) for fn in file_names]
# 现在在“files”列表中拥有所有打开的文件
# 对文件执行操作...
for file in files:
# 处理每个文件...
# 所有文件将在退出“with”块时自动关闭
在这个例子中:
-
我们创建一个
ExitStack
对象,使用with
语句将其命名为stack
。 -
我们使用列表推导来迭代
file_names
列表。 -
对于每个文件名,我们使用
stack.enter_context(open(fn))
打开文件。这会打开文件,并通过__enter__
方法调用其上下文管理器,并注册一个回调,在with
块结束时使用ExitStack
关闭文件。 -
打开的文件句柄被收集在一个名为
files
的列表中。 -
现在可以使用
files
列表访问打开的文件,并在with
块内对它们执行操作。 -
当
with
块退出时(无论是否正常或引发异常),ExitStack
确保所有打开的文件通过其各自的__exit__
方法正确关闭。
此方法提供了与为每个文件使用单独的
with
语句类似的行为,同时允许在运行时处理任意数量的文件。