在Python中嵌套'WITH'语句

时间:2010-01-02 02:18:13

标签: python append with-statement

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

有谁知道在python中使用语句嵌套是什么意思?
我一直在追踪一个我写过的剧本中的一个非常滑的错误,我怀疑这是因为我这样做:

with open(file1) as fsock1:
    with open(file2, 'a') as fsock2:
        fstring1 = fsock1.read()
        fstring2 = fsock2.read()
当我尝试从fsock2 read()时,Python会抛出。在调试器中检查时,这是因为它认为文件是空的。除了在with语句中运行完全相同的代码而不在with语句中的事实表明该文件实际上充满了文本之外......这不会令人担忧。

我将继续假设现在嵌套{{1}}语句是禁止的,但如果知道更多的人有不同意见,我很乐意听到。

5 个答案:

答案 0 :(得分:9)

我在python的doc中找到了解决方案。您可能需要查看this (Python 3)this (Python 2)

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

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

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

答案 1 :(得分:6)

AFAIK您无法读取以附加模式'a'打开的文件。

答案 2 :(得分:4)

  

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

我认为这是因为它实际上无法读取任何内容。即使可以,当您追加到文件时,搜索指针也会移动到文件的末尾,以准备进行写入。

这些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):
   ...

这里的上下文管理器一次创建一个。这意味着如果file2的打开失败(例如,因为它不存在),那么你将无法正确地完成file1,你将不得不将它留给垃圾收集器。这可能是一件非常糟糕的事情。

答案 3 :(得分:1)

嵌套with语句没有问题 - 相反,您正在打开file2进行追加,因此您无法从中读取。

如果您不喜欢嵌套with语句,无论出于何种原因,您通常可以使用contextlib.nested函数来避免这种情况。但是,它不会使破坏的代码(例如,打开文件以进行追加然后尝试读取它的代码)工作,也不会在词法上嵌套with语句破坏其他方面的代码。

答案 4 :(得分:0)

至于搜索“with”,在单词前加上“+”会阻止Google忽略它。