How to use the command "with" conditionally without duplication of code

Question:

I am trying to use with before executing a block of code, but only if a condition is met, but (at least the common) usage of with doesn’t appear to support that unless I duplicate the block of code.

More concretely, I know I can do the following:

if condition:
    with blah_blah():
        my_code_block
else:
    my_code_block

But that’s unsatisfying during development since any change I make to my_code_block must be made twice. What I want to do (conceptually) is:

if condition:
    with blah_blah():
else:
    my_code_block

That doesn’t work, though. Is there a way to accomplish what I’m trying to do?

For anyone that’s interested in my particular use, I’m trying to write code that runs a batch of examples in pytorch, with torch.no_grad() if I’m in evaluation mode and without it if I’m in train mode. So what I want to do becomes

if mode == 'eval':
    with torch.no_grad():
else:
    run_batch(features, labels)
Asked By: BioBroo

||

Answers:

Use the with statement, but with a nullcontext context manager if necessary.

from contextlib import nullcontext

with blah_blah() if condition else nullcontext():
    my_code_block

nullcontext takes an optional argument that it will return if your with statement expects something to be bound with as. For example,

with nullcontext("hello") as f:
    print(f)  # outputs "hello"
Answered By: chepner

I was wondering if it could be accomplished with:

def myrunner(myfunc,usecontext=True):
    if usecontext:
        with blahblah():
             myfunc()
    else:
        myfunc()

def myfunc()...

myrunner(myfunc,usecontext=false)

But looking at it, I don’t see how the context can effect myfunc.

Answered By: RufusVS
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.