事实证明,在互联网上搜索“with”是一个有趣的词。

有谁知道 python 中嵌套 with 语句是怎么回事?
我一直在我编写的脚本中追踪一个非常棘手的错误,我怀疑这是因为我正在这样做:

with open(file1) as fsock1:
    with open(file2, 'a') as fsock2:
        fstring1 = fsock1.read()
        fstring2 = fsock2.read()

当我尝试时 Python 会抛出 read() 来自 fsock2。在调试器中检查后,这是因为它认为该文件是空的。这并不令人担忧,除了在调试解释器中运行完全相同的代码而不是在 with 声明显示该文件实际上充满了文本......

我将继续假设现在嵌套 with 陈述是禁忌,但如果任何了解更多的人有不同的意见,我很想听听。

有帮助吗?

解决方案

我在python的文档中找到了解决方案。您可能想看看 这个(Python 3) 或者 这个(Python 2)

如果您运行的是 python 2.7+,您可以像这样使用它:

with open(file1) as fsock1, open(file2, 'a') as fsock2:
    fstring1 = fsock1.read()
    fstring2 = fsock2.read()

这样可以避免不必要的缩进。

其他提示

AFAIK不能读取与附加模式'a'文件打开。

  

当在调试器检查,这是因为它认为文件为空。

我觉得这种情况发生,因为它不能真正读什么。即使可以,当你追加到一个文件,指针移动到文件的末尾,准备写发生求。

这些with声明只是正常工作对我来说:

with open(file1) as f:
    with open(file2, 'r') as g:   # Read, not append.
        fstring1 = f.read()
        fstring2 = g.read()

请注意,使用contextlib.nested的,作为另一种建议的海报,是具有危险这里可能充满。比方说,你这样做:

with contextlib.nested(open(file1, "wt"), open(file2)) as (f_out, f_in):
   ...

这里的上下文管理器获得创建一次一个。这意味着,如果文件2开幕失败(比如,因为它不存在),那么你将不能够正常的finalize文件1,你就必须把它留给垃圾回收器。这是一个潜在的非常糟糕的事情。

有与嵌套with报表没有问题 - 相反,你可以进行追加是开放file2,所以你不能从它读

如果你不喜欢筑巢with陈述,不管什么原因,你可以经常避免与的 contextlib.nested 功能。但是,它不会使断码(例如,打开用于追加一个文件,然后代码试图读取它来代替)的工作,也不会词法嵌套with语句断码这本来很好的。

作为用“+”将防止忽略它谷歌搜索“带有”前缀一个字。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top