我明白了why contextlib.nested is deprecated .
但是如果我为旧的 python 版本编写程序而没有 with 的多种形式(即 < 2.7),我(几乎)别无选择。
为了避免下面的构造失败:
with nested(open("f1"), open("f2")) as (f1, f2):
(如果打开f2
失败,f1
不会关闭,因为没有进入contextmanager)
我可以想象编写一个上下文管理器,将初始化移动到它的 __enter__
中:
@contextmanager
def late_init(f, *a, **k):
r = f(*a, **k)
with r as c: yield c
我这样想对吗
with nested(late_init(open, "f1"), late_init(open, "f2")) as (f1, f2):
这里足以使其“干净”吗?
给出的用例只是一个例子。想象一下,您有一个文件列表,其长度不是过早已知的。那么 2.7 组合的 with
和带有多个缩进 with
语句的 pre-2.7 嵌套方式都不可用。
我可能不得不说得更详细一些。
上述解决方案乍一看解决了问题:调用函数是在安全的地方执行的,因此可以检测到故障并进行适当处理。
我的问题是:它能解决缺陷,还是会带来其他问题?
最佳答案
contextlib.nested 工具用于将上下文管理器组合成一个。它已被弃用,因为它存在设计缺陷(对于您显示的情况,如果打开 f2 失败,则不会关闭 f1)。
虽然您的用例不需要组合。常规嵌套就足够了:
with open('f1') as f1:
with open('f2') as f2:
...
关于python - contextlib.nested 中的怪癖解决方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9859086/