In Python, the following pattern is quite common.
thing = x and load_thing(x)
which propagates None
through your code (if x
is None
then so is thing
). This is useful because later in your code you can check if thing
is None and have different logic.
I'm not sure how to man this play well with context managers: the following code does not work (because if x is None, with None as y
is not valid (because None does not have __enter__
)
with x and load_thing(x) as y:
f(y)
The best thing I've come up with is this, but I think the people reading my code might curse me (no sense of fun I tell you, no sense of fun).
@contextlib.contextmanager
def const_manager(x):
yield x
with (const_manager(x) if x is None else load_thing(x)) as y:
f(y)
Is there a more pythonic alternative? Besides layers and layers of function definitions and calls.
Put the test in your wrapper context manager.
@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)
You might also consider using contextlib.nullcontext
instead.
with (load_thing if x is not None else nullcontext)(x) as y:
f(y)