I have a five or six resources that have nice 'with' handlers, and normally I'd do this:
with res1, res2, res3, res4, res5, res6:
   do1
   do2
However, sometimes one or more of these resources should not be activated. Which leads to very ugly repetitive code:
 with res1, res3, res4, res6: # these always acquired
    if res2_enabled:
        with res2:
           if res5_enabled:
               with res5:
                  do1
                  do2
           else:
              do1
              do2
     else if res5_enabled:
        with res5:
           ...
There must be clean easy ways to do this surely?
You could create a wrapper object that supports the with statement, and do the checking in there. Something like:
with wrapper(res1), wrapper(res2), wrapper(res3):
   ...
or a wrapper than handles all of them:
with wrapper(res1, res2, res3):
   ...
The definition for you wrapper would be:
class wrapper(object):
    def __init__(self, *objs):
        ...
    def __enter__(self):
        initialize objs here
    def __exit__(self):
        release objects here
                        If I understand you correctly you can do this:
from contextlib import contextmanager, nested
def enabled_resources(*resources):
    return nested(*(res for res,enabled in resources if enabled))
# just for testing
@contextmanager
def test(n):
    print n, "entered"
    yield
resources = [(test(n), n%2) for n in range(10)]
# you want
# resources = [(res1, res1_enabled), ... ]
with enabled_resources(*resources):
    # do1, do2
    pass
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With