I’ve some code like this:
with SomeContext(args):
<statement1>
.
.
<statementN>
I want this code to behave like this:
if some_condition(args):
f1()
else:
<statement1>
.
.
<statementN>
Statements in else block will also need an access to args.
But I want to hide f1 and some_condition from user of this abstraction, so using an if-else block is out of option. Also I don’t want to force a constraint on the user to wrap all statements in a function. Is it possible to do some python magic in the with context that allows this?
The closest I can get is to use two nested context managers, something like the following:
The
SkipContextmanager essentially catches theSkippedExceptionraised by the innerSomeContextmanager in the case wherearg == 1.Note that the syntax of multiple context expressions is only supported in Python 2.7 or later. In earlier versions, you would have to write:
The
contextlib.nestedcontext manager, despite claims in the documentation, doesn’t exactly match the semantics of the above nestedwithstatement when exceptions are thrown from within__enter__, so it doesn’t work in this case.It should be noted that PEP 343 mentions that macros (like context managers) that hide flow control should be discouraged, and references Raymond Chen’s rant against hidden flow control.