gpt4 book ai didi

python - 分解 with 语句

转载 作者:太空狗 更新时间:2023-10-30 01:56:33 28 4
gpt4 key购买 nike

最初,我一直在打开并同时阅读两个文件,内容如下:

with open(file1, 'r') as R1:
with open(file2, 'r') as R2:
### my code

但现在输入的文件名有时可能会被 gzip 压缩。所以,我想拆分 with 语句并使用 if 语句来处理这两种情况,如下所示:

if zipped:
R1 = gzip.open(file1, 'r')
R2 = gzip.open(file2, 'r')
else:
R1 = open(file1, 'r')
R2 = open(file2, 'r')

with R1:
with R2:
### my code

第二个代码的功能与第一个相同吗?还是有更好的方法来做到这一点?

最佳答案

你所做的大部分是有道理的,但它有一个问题。


文件对象是在__exit__关闭 自身的上下文管理器。作为gzip文档清楚地表明,其中包括 gzip.open 返回的 GzipFile 对象:

GzipFile supports the io.BufferedIOBase interface, including iteration and the with statement.

因此,如果您在打开的常规文件或 GzipFile 上编写 with f:,则可以保证 close 将在 with 语句。

在 Python 2.7 中,细节略有不同,但工作方式相同。在 Python 2.6 中,GzipFile 不是上下文管理器。但是有一个非常简单的解决方案(对于其他类型值得了解,即使您不关心 Python 2.6):您可以使用 closing 中的 close 方法包装任何内容。获取在 __exit__ 上调用 close 的上下文管理器。所以,你可以这样写:

with contextlib.closing(R1):

… 它可以在 R1 上工作,无论它是一个文件对象,还是其他不知道如何成为的东西(比如 2.6 GzipFile)上下文管理器。


但是,如果 R1 打开成功,但是 R2 打开失败会怎样?然后你甚至还没有进入 with R1: 引发异常时,所以你永远不会关闭 R1

您可以通过在打开 R2 之前执行 with R1 来解决此问题:

if zipped:
R1 = gzip.open(file1, 'r')
else:
R1 = open(file1, 'r')
with R1:
if zipped:
R2 = gzip.open(file2, 'r')
else:
R2 = open(file2, 'r')
with R2:

或者您可以使用 ExitStack .

但是这里有一个更简单的解决方案:gzip.openopen 都是可调用对象,因此您可以将它们存储在一个变量中,稍后调用它。由于它们具有相同的签名,并且您想使用完全相同的参数调用它们,因此使用该变量很简单:

if zipped:
zopen = gzip.open
else:
zopen = open
with zopen(file1, 'r') as R1:
with zopen(file2, 'r') as R2:

请注意,您可以在不降低可读性的情况下使其更加简洁:

zopen = gzip.open if zipped else open
with zopen(file1, 'r') as R1, zopen(file2, 'r') as R2:

关于python - 分解 with 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51293326/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com