首页 > 解决方案 > 如何在 Python 中同时打开多个文件?

问题描述

我有一些文件(其数量未确定),我想逐行或分块同时读取,进行一些处理并移至所有文件中的下一行(或块)。我想我的要求与这个问题中的要求或多或少相似。但是,在我的情况下,文件可以有不同的行数,并且在尝试实现类似ExitStack的东西时,注意到所有文件将在其中一个关闭后立即关闭(可能是行数最少的文件) ,而我想继续处理其他文件(最终将空字符串分配给已关闭文件的“行”)。这有可能实现吗?如何?

#cat f1.txt
RNvn 40
AvOp 13
yEVA 94
oNGn 10
VZQU 88

#cat f2.txt
gSNn 4
zxHP 84
ebRw 70
NaxL 2
lXUb 49
PQzn 79
aIyN 88

#cat f3.txt
XXce 5
RMIq 4
FFEi 47
wuLZ 60

使用 的简单实现ExitStack,结果只包含 4 行,因为 filef3.txt只有 4 行:

flist = ['f1.txt', 'f2.txt', 'f3.txt']
with ExitStack() as stack:
    files = [stack.enter_context(open(fname)) for fname in flist]
    for lines in zip(*files):
        print(lines)

# prints
('RNvn 40\n', 'gSNn 4\n', 'XXce 5\n')
('AvOp 13\n', 'zxHP 84\n', 'RMIq 4\n')
('yEVA 94\n', 'ebRw 70\n', 'FFEi 47\n')
('oNGn 10\n', 'NaxL 2\n', 'wuLZ 60\n')

标签: python-3.xfile

解决方案


您可以使用两全其美。

该代码正在离开上下文with ExitStack() as stack:,因为zip()在最短的文件上已用尽。它与 . 无关ExitStack()。在所有文件完成之前,使用zip_longest()不会耗尽。然后ExitStack()将关闭文件。

from contextlib import ExitStack
from itertools import zip_longest

flist = ['f1.txt', 'f2.txt', 'f3.txt']
with ExitStack() as stack:
    files = [stack.enter_context(open(fname)) for fname in flist]
    for lines in zip_longest(*files):
        print(lines)

推荐阅读