在 Python 中嵌套“WITH”语句
Posted
技术标签:
【中文标题】在 Python 中嵌套“WITH”语句【英文标题】:Nesting 'WITH' statements in Python 【发布时间】:2010-12-31 17:08:30 【问题描述】:事实证明,“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】:我在 python 的文档中找到了解决方案。你可能想看看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()
这样可以避免不必要的缩进。
【讨论】:
【参考方案2】:AFAIK 您无法读取以附加模式打开的文件 'a'
。
【讨论】:
当我意识到同样的事情时,我正要评论我自己的问题。我觉得……现在很傻。【参考方案3】:在调试器中检查,这是因为它认为文件是空的。
我认为这是因为它实际上无法读取任何内容。即使可以,当您追加到文件时,查找指针也会移动到文件的末尾以准备写入。
这些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 并且您必须将其留给垃圾收集器。这可能是一件非常糟糕的事情。
【讨论】:
"...那么您将无法正确完成..." 这是不正确的。基于Python docs,第二个with
语句将在第一个语句开始之前不会执行。复合 with
语句在语义上等同于嵌套的 with
语句。【参考方案4】:
嵌套with
语句没有问题——相反,您打开file2
进行追加,因此您无法从中读取。
如果您不喜欢嵌套with
语句,无论出于何种原因,您通常可以使用contextlib.nested 函数来避免这种情况。但是,它不会使损坏的代码(例如,打开文件以进行追加然后尝试读取它的代码)工作,也不会在词法上嵌套 with
语句破坏本来很好的代码。
【讨论】:
【参考方案5】:至于搜索“with”,在词前加上“+”可以防止google忽略。
【讨论】:
这曾经是真的。现在你必须用引号括起来,即"with"
。
这不是手头问题的答案(是的,我知道这个问题已有 10 年历史了)以上是关于在 Python 中嵌套“WITH”语句的主要内容,如果未能解决你的问题,请参考以下文章
VB 的 with 语句中语句能嵌套循环语句吗?比如for next