Sometimes I need the following pattern within a for
loop. At times more than once in the same loop:
try:
var = 'attempt to do something that may fail on a number of levels'
except Exception, e:
log(e)
continue
Now I don't see a nice way to wrap this in a function as it can not return continue
:
def attempt(this):
try:
return this
except Exception, e:
log(e)
# 1. continue # <-- syntax error: continue not properly in loop or
# 2. return continue # <-- invalid syntax
# 3.
return False # <-- this sort of works, but makes me feel powerless
If I return False
than I could:
var = attempt('to do something that may fail on a number of levels')
if not var:
continue
But I don't feel that does it the justice. I want to tell the for loop to continue
(or fake it) from within attempt
function.
Maybe you want to do continuations? You could go and look at how Eric Lippert explains them (if you are ready to have your mind blown, but in Python it could look a bit like this:
Inside your loop you could do:
Apart from the context I just want to answer the question in a brief fashion. No, a function cannot
continue
a loop it may be called in. That is because it has no information about this context. Also, it would raise a whole new class of questions like what shall happen if that function is called without a surrounding loop to handle thatcontinue
?BUT a function can signal by various means that it wants the caller to
continue
any loop it currently performs. One means of course is the return value. ReturnFalse
orNone
to signal this for example. Another way of signaling this is to raise a specialException
:Edit: Removed all that stupidity I said...
The final answer was to rewrite the whole thing, so that I don't need to code like that.
put the for loop outside the try, except block ... simple... ;-)
I wouldn't normally post a second answer, but this is an alternative approach if you really don't like my first answer.
Remember that a function can return a
tuple
.I maintain that
try ... except ... else
is the way to go, and you shouldn't silently ignore errors though. Caveat emptor and all that.Python already has a very nice construct for doing just this and it doesn't use
continue
:I wouldn't nest any more than this, though, or your code will soon get very ugly.
In your case I would probably do something more like this as it is far easier to unit test the individual functions and flat is better than nested:
Remember to always catch specific exceptions. If you were not expecting a specific exception to be thrown, it is probably not safe to continue with your processing loop.
Edit following comments:
If you really don't want to handle the exceptions, which I still think is a bad idea, then catch all exceptions (
except:
) and instead ofhandle(e)
, justpass
. At this pointwrap_process()
will end, skipping theelse:
-block where the real work is done, and you'll go to the next iteration of yourfor
-loop.Bear in mind, Errors should never pass silently.