with
giving you trouble? Throw more with
-able objects at the problem!
class fragile(object):
class Break(Exception):
"""Break out of the with statement"""
def __init__(self, value):
self.value = value
def __enter__(self):
return self.value.__enter__()
def __exit__(self, etype, value, traceback):
error = self.value.__exit__(etype, value, traceback)
if etype == self.Break:
return True
return error
Just wrap the expression you’re going to with
with fragile
, and raise fragile.Break
to break out at any point!
with fragile(open(path)) as f:
print 'before condition'
if condition:
raise fragile.Break
print 'after condition'
Benefits of this setup
- Uses
with
and just thewith
; doesn’t wrap your function in a semantically misleading one-run ‘loop’ or a narrowly specialized function, and doesn’t force you to do any extra error handling after thewith
. - Keeps your local variables available, instead of having to pass them to a wrapping function.
-
Nestable!
with fragile(open(path1)) as f: with fragile(open(path2)) as g: print f.read() print g.read() raise fragile.Break print "This wont happen" print "This will though!"
This way, you don’t have to create a new function to wrap the outer
with
if you want both to break. - Doesn’t require restructuring at all: just wrap what you already have with
fragile
and you’re good to go!
Downsides of this setup
- Doesn’t actually use a ‘break’ statement. Can’t win em all 😉