我一直在使用许多上下文管理器作为组合各种设置/拆卸情况的干净方法。因为我的部署目标是Python2.6,所以这意味着使用contextlib.nested。
最近,我对用相同的代码库支持Python2.x和Python3很感兴趣。这在一些项目中是可能的,但是我在上下文管理器方面遇到了麻烦,因为:
contextlib.nestedwith aa() as a, bb() as b: ...)。这里有一个基本的句法不兼容。由于我无法控制的各种原因,2.7目前可能很难投入生产,但我希望将来尽可能多地验证代码,因此对Python 3感兴趣。
有人能为2.6和3.x的代码库中的嵌套上下文管理器提供支持吗?或者这是一个失败的原因?
发布于 2013-10-01 21:28:23
从医生那里:
这一职能有两个主要的怪癖,导致它被废弃。首先,由于上下文管理器都是在调用函数之前构造的,外部上下文管理器的范围并不包括内部上下文管理器的
__new__()和__init__()方法。例如,这意味着使用nested()打开两个文件是编程错误,因为如果打开第二个文件时抛出异常,第一个文件将不会立即关闭。 其次,如果一个内部上下文管理器的__enter__()方法引发一个异常,被外部上下文管理器的__exit__()方法捕获和抑制,则此构造将引发RuntimeError,而不是跳过with语句的正文。
因此,在几乎所有的情况下,正确的答案都是JBernardo的,它是更多的缩进,但它也有一点小问题。
发布于 2013-10-01 21:24:34
只要把它们筑巢
with aa() as a:
with bb() as b:
#some code here发布于 2013-10-01 21:42:05
如果Veedrac提到的nested的怪癖对您来说不是问题,那么您只需从Python库中复制代码即可。
如果它们确实困扰您,那么您唯一的选择就是手动嵌套它们,或者放弃Python2.6支持。不管您是使用两个代码库还是使用一个代码库都不重要。如果是这样的话,那么它在Python2.6中工作的唯一方法就是嵌套它们。我想您可以编写某种定制的2到3修复程序,将未嵌套的2.7代码转换为嵌套的2.6代码。但是老实说,只在嵌套的管理器中使用单个代码库就不会那么痛苦了,直到您可以放弃2.6支持为止。
https://stackoverflow.com/questions/19126182
复制相似问题