Conditional Python with

I have five or six resources that have good β€œwith” handlers, and normally I would do this:

with res1, res2, res3, res4, res5, res6: do1 do2 

However, sometimes one or more of these resources do not have to be activated. This leads to a very ugly repeating 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: ... 

Should there be clean simple ways to do this, of course?

+4
source share
3 answers

The original poster is here; here is my approach so far refined:

I can add (or monkey-patch) the bool __nonzero__ operator to objects with objects, returning whether they are included. Then, when the objects are mutually exclusive, I can have:

 with res1 or res2 or res3 or res4: ... 

When a resource is togglable, I can create an empty one that is nop; wither seems like a nice name for him:

 class sither: @classmethod def __enter__(cls): pass @classmethod def __exit__(cls,*args): pass ... with res1 or wither, res2 or wither: ... 

I can also use this while retaining the ability to switch from suitable objects:

 with res1 if res1enabled else wither, res2 if res2enabled else wither: .. 

Finally, those whom I control most, I can integrate the included check into the class itself, so when they are used and not included, they nop:

 with res1, res2, res3: ... 

The with operator is absolutely adored; it is still a bit fragmented. It will be interesting to see what refinement others have in this regard ...

0
source

You can create a wrapper object that supports the with statement and perform validation there. Sort of:

 with wrapper(res1), wrapper(res2), wrapper(res3): ... 

or a wrapper, which processes all of them:

 with wrapper(res1, res2, res3): ... 

The definition for your shell will be:

 class wrapper(object): def __init__(self, *objs): ... def __enter__(self): initialize objs here def __exit__(self): release objects here 
+5
source

If you understand 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 
+5
source

All Articles