有没有办法在 with 语句中关闭多个打开的文件中的一个,以便在条件后只写入其中的一个子集?

Is there a way to close 1 of multiple open files in with statement to just write to a subset of them after a condition?

我想使用 with 语句从一个文件读取并写入 2 个文件中的任何一个,而不是同时写入这两个文件。

我希望使用 with 语句执行此操作,以避免在出于好奇移动代码时不关闭文件。

我下面的代码只写入 out1File。我想关闭 out1File 以便只写入 out2File 但我不确定如果我这样做会发生什么,因为 with 应该根据我的理解为我关闭文件.

使用不同的 openclose 语句是否更好?

with open('input.txt', mode='r') as inputFile, \
     open('output1.txt', mode='w') as out1File,     \
     open('output2.txt', mode='w') as out2File:
    lines = inputFile.readlines()
    isInput1 = False
    isInput2 = False
    for line in lines:
        if line.startswith("out1"):
            isInput1 = True
            continue
        elif isInput1:
            out1File.write(line.replace(":", " "))
        elif line.startswith("out2"):
            isInput1 = False
            isInput2 = True
            continue
        elif isInput2:
            out2File.write(line.replace(":", " "))

我猜问题出在 if 结构上。

当您将 line.startswith("out2") 与主 if 块粘贴在一起并且也没有在第一个块中设置 isInput2 = False 时,它假定该行始终以 out1 开头,因为 isInput1 结果总是正确的。

我做的就是把检查条件分组,完成变量交换

也许我解决这个问题的方法不是最好的技术,但如果你想坚持你的代码结构,我想这会奏效:

with open('input.txt', mode='r') as inputFile, \
 open('output1.txt', mode='w') as out1File,     \
 open('output2.txt', mode='w') as out2File:
lines = inputFile.readlines()
isInput1 = False
isInput2 = False
for line in lines:
    if line.startswith("out1"):
        isInput1 = True
        isInput2 = False
        continue
    elif line.startswith("out2"):
        isInput2 = True
        isInput1 = False
        continue
    if isInput1:
        out1File.write(line.replace(":", " "))
    elif isInput2:
        out2File.write(line.replace(":", " "))

上下文管理器只是一个 class,运行 是一个 .__enter__() 方法和 .__exit__() 方法。即使出现错误,exit 方法也会自动 运行,这就是为什么它用于在发生错误后关闭文件的原因。内置的 open.__exit__() 看起来像这样:

def __exit__(*errors,**kerrors):
    self.close()

这意味着 open() 运行s .close() 在“with 语句”的末尾,即使在“with 语句”期间发生错误。如果你 运行, .close() 在“with 语句”里面相当于 运行ning .close() 两次(一次在 with 语句中,一次在 with 语句结束时)。 运行 .close() 在已经关闭的文件上不执行任何操作,也不应该成为问题,因此您可以根据需要在 with 语句期间关闭文件。