在 Python 中嵌套“WITH”语句
-
22-09-2019 - |
题
事实证明,在互联网上搜索“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
语句断码这本来很好的。
作为用“+”将防止忽略它谷歌搜索“带有”前缀一个字。