如何在 Python 中使用“with open”打开多个文件?
- 2024-12-24 08:55:00
- admin 原创
- 56
问题描述:
我想一次更改几个文件,前提是我可以写入所有文件。我想知道我是否可以以某种方式将多个 open 调用与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:
从 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"
请注意,通常您希望按顺序处理文件,而不是同时打开所有文件,特别是当您有可变数量的文件时:
for fname in filenames:
with open(fname) as f:
# Process f
解决方案 2:
只需替换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
解决方案 3:
对于一次打开多个文件或较长的文件路径,将文件拆分成多行可能很有用。摘自@Sven Marnach 在另一个答案的评论中建议的Python 样式指南:
with open('/path/to/InFile.ext', 'r') as file_1, \n open('/path/to/OutFile.ext', 'w') as file_2:
file_2.write(file_1.read())
解决方案 4:
从 Python 3.10 开始,有一个新功能,即括号上下文管理器,它允许如下语法:
with (
open("a", "w") as a,
open("b", "w") as b
):
do_something()
解决方案 5:
ExitStack
从 Python 3.3 开始,您可以使用模块中的类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 ExitStack
class X:
num = 1
def __init__(self):
self.num = X.num
X.num += 1
def __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.num
def __exit__(self, exc_type, exc_value, traceback):
print('exit {!r}'.format(self))
return True
xs = [X() for _ in range(3)]
with ExitStack() as stack:
print(len(stack._exit_callbacks)) # number of callbacks called on exit
nums = [stack.enter_context(x) for x in xs]
print(len(stack._exit_callbacks))
print(len(stack._exit_callbacks))
print(nums)
输出:
0
enter X1
enter X2
enter X3
3
exit X3
exit X2
exit X1
0
[1, 2, 3]
解决方案 6:
嵌套的 with 语句可以完成相同的工作,而且在我看来,处理起来更加直接。
假设您有 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,就像问题要求的那样。没有重复写入或写入失败。所以我真的很好奇为什么我的答案被认为是错误的、次优的或诸如此类的。
解决方案 7:
使用 python 2.6 它将不起作用,我们必须使用下面的方式打开多个文件:
with open('a', 'w') as a:
with open('b', 'w') as b:
解决方案 8:
答案迟了(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))
2018-10-23 19:18:11.361 PROFILE [Stop Drivers] [1ms]
2018-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
...
解决方案 9:
如果要保留原始换行符,即使文件已在多个不同的操作系统上编辑和保存,也可能出现以下换行符:\n(LN 换行符),用于 Linux \r\n(CR 回车符,LN 换行符),用于 Microsoft Windows OS \r,用于旧版本的 Mac 以及 OpenBSD 等 Unix 操作系统
以二进制模式打开文件
with open('example.txt', 'rb') as f:
content = f.read()
将字节解码为字符串(假设为 UTF-8 编码),保留原始换行符
content_str = content.decode('utf-8')
现在**content_str**
将具有文件中出现的原始换行符
print(repr(content_str)) # 使用 repr 在输出中显示换行符
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理必备:盘点2024年13款好用的项目管理软件