Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

conditional python with

Tags:

python

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?

like image 678
Will Avatar asked Dec 21 '22 12:12

Will


2 Answers

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
like image 141
rafalotufo Avatar answered Dec 24 '22 01:12

rafalotufo


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
like image 32
Jochen Ritzel Avatar answered Dec 24 '22 01:12

Jochen Ritzel