I\'d just like to exit out of a with
statement under certain conditions:
with open(path) as f:
print \'before condition\'
if
Since break
can only occur inside a loop your options are somewhat limited inside the with
to:
Having a function and using return
is probably the cleanest and easiest solution here if you can isolate the with
and the associated statements (and nothing else) inside a function.
Otherwise generate an exception inside the with
when needed, catch immediately below/outside the with
to continue the rest of the code.
Update: As OP suggests in the comments below (perhaps tonuge in cheek?) one could also wrap the with
statement inside a loop to get the break
to work - though that would be semantically misleading. So while a working solution, probably not something that would be recommend).
You could put everything inside a function, and when the condition is true call a return.
Change from "break" to "f.close"
with open(path) as f:
print('before condition')
if <condition>: f.close()
print('after condition')
The best way would be to encapsulate it in a function and use return
:
def do_it():
with open(path) as f:
print 'before condition'
if <condition>:
return
print 'after condition'
There exists a function __exit__()
for this purpose. Syntax is as follows:
with VAR = EXPR:
try:
BLOCK
finally:
VAR.__exit__()
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'
with
and just the with
; 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 the with
.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.
fragile
and you're good to go!