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

How should I handle None's in context managers in python?

在Python中,下面的模式很常见。

thing = x and load_thing(x)

通过您的代码传播 None(如果 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)

有没有更pythonic的替代品?除了一层又一层的函数定义和调用。

不要让 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
    # ...

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

@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)