如何在 Python 中使用“with open”打开多个文件?

2024-12-24 08:55:00
admin
原创
116
摘要:问题描述:我想一次更改几个文件,前提是我可以写入所有文件。我想知道我是否可以以某种方式将多个 open 调用与with语句结合起来:try: with open('a', 'w') as a and open('b', 'w') as b: do_something() except IOErro...

问题描述:

我想一次更改几个文件,前提是我可以写入所有文件。我想知道我是否可以以某种方式将多个 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 在输出中显示换行符

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用