我想一次更改几个文件,前提是我可以写入所有文件。 我想知道我是否可以将多个打开调用与with
语句结合with
:
try:with open('a', 'w') as a and open('b', 'w') as b:do_something()except IOError as e:print 'Operation failed: %s' % e.strerror
如果不可能,那么解决该问题的优雅解决方案会是什么样?
#1楼
对于一次打开多个文件或较长的文件路径,将内容分解成多行可能很有用。 @Sven Marnach在《 Python样式指南》中对另一个答案的评论中建议:
with open('/path/to/InFile.ext', 'r') as file_1, \open('/path/to/OutFile.ext', 'w') as file_2:file_2.write(file_1.read())
#2楼
从Python 2.7(或分别为3.1)开始,您可以编写
with open('a', 'w') as a, open('b', 'w') as b:do_something()
在早期版本的Python中,有时可以使用contextlib.nested()
嵌套上下文管理器。 但是,这对于打开多个文件无法正常工作-有关详细信息,请参见链接的文档。
在极少数情况下,您想同时打开全部数量可变的文件,可以使用contextlib.ExitStack
,从Python 3.3版本开始:
with ExitStack() as stack:files = [stack.enter_context(open(fname)) for fname in filenames]# Do something with "files"
大多数情况下,您拥有一组可变的文件,但是您可能想要一个接一个地打开它们。
#3楼
只需将and
替换为,
就可以完成:
try:with open('a', 'w') as a, open('b', 'w') as b:do_something()except IOError as e:print 'Operation failed: %s' % e.strerror
#4楼
嵌套语句可以完成相同的工作,我认为处理起来更简单。
假设您有inFile.txt,并想同时将其写入两个outFile。
with open("inFile.txt", 'r') as fr:with open("outFile1.txt", 'w') as fw1:with open("outFile2.txt", 'w') as fw2:for line in fr.readlines():fw1.writelines(line)fw2.writelines(line)
编辑:
我不了解拒绝投票的原因。 我在发布答案之前测试了我的代码,它可以按预期工作:就像问题所要求的那样,它写入所有outFile。 无重复写入或写入失败。 因此,我真的很想知道为什么我的答案被认为是错误的,次优的或类似的东西。
#5楼
使用python 2.6它将无法正常工作,我们必须使用以下方式打开多个文件:
with open('a', 'w') as a:with open('b', 'w') as b:
#6楼
因为Python 3.3,你可以使用类ExitStack
从contextlib
模块安全
打开任意数量的文件。
它可以管理动态数量的上下文感知对象,这意味着如果您不知道要处理多少个文件,它将证明特别有用。
实际上,文档中提到的规范用例正在管理动态数量的文件。
with ExitStack() as stack:files = [stack.enter_context(open(fname)) for fname in filenames]# All opened files will automatically be closed at the end of# the with statement, even if attempts to open files later# in the list raise an exception
如果您对这些细节感兴趣,下面是一个通用示例,以说明ExitStack
工作方式:
from contextlib import ExitStackclass X:num = 1def __init__(self):self.num = X.numX.num += 1def __repr__(self):cls = type(self)return '{cls.__name__}{self.num}'.format(cls=cls, self=self)def __enter__(self):print('enter {!r}'.format(self))return self.numdef __exit__(self, exc_type, exc_value, traceback):print('exit {!r}'.format(self))return Truexs = [X() for _ in range(3)]with ExitStack() as stack:print(len(stack._exit_callbacks)) # number of callbacks called on exitnums = [stack.enter_context(x) for x in xs]print(len(stack._exit_callbacks))print(len(stack._exit_callbacks))print(nums)
输出:
0enter X1enter X2enter X33exit X3exit X2exit X10[1, 2, 3]
#7楼
回答较晚(8年),但对于希望将多个文件合并为一个文件的人,以下功能可能会有所帮助:
def multi_open(_list):out=""for x in _list:try:with open(x) as f:out+=f.read()except:pass# print(f"Cannot open file {x}")return(out)fl = ["C:/bdlog.txt", "C:/Jts/tws.vmoptions", "C:/not.exist"]print(multi_open(fl))
-10-23 19:18:11.361 PROFILE [Stop Drivers] [1ms]-10-23 19:18:11.361 PROFILE [Parental uninit] [0ms]...# This file contains VM parameters for Trader Workstation.# Each parameter should be defined in a separate line and the...