我应该如何在 python 的上下文管理器中处理 None?



在Python中,以下模式非常常见。

thing = x and load_thing(x)

它通过您的代码传播CCD_ 1(如果xNone,则thing也是(。这很有用,因为在稍后的代码中,您可以检查thing是否为None并具有不同的逻辑。

我不知道如何用上下文管理器很好地处理这一问题:以下代码不起作用(因为如果x为None,则with None as y无效(因为None没有__enter__(

with x and load_thing(x) as y:
f(y)

我想出的最好的办法是这样,但我认为阅读我代码的人可能会诅咒我(我告诉你,没有乐趣的感觉,没有乐趣的感觉(。

@contextlib.contextmanager
def const_manager(x):
yield x

with (const_manager(x) if x is None else load_thing(x)) as y:
f(y)

还有比蟒蛇更好的选择吗?除了一层又一层的函数定义和调用。

将测试放入包装器上下文管理器中。

@contextlib.contextmanager
def default_manager(cm, x):
if x is None
yield x
else:
yield cm(x)

with default_manager(load_thing, x) as y:
f(y)

您也可以考虑使用contextlib.nullcontext

with (load_thing if x is not None else nullcontext)(x) as y:
f(y)

不要让None到达您的上下文管理器。

# ...
if x is None:
return None  # or raise SomeException, depends on context
# ...
with my_context(x) as c:  # Here we do have something to play with
# ...

最新更新