Python: Using continue in a try-finally statement in a loop - python

Will the following code:
while True:
try:
print("waiting for 10 seconds...")
continue
print("never show this")
finally:
time.sleep(10)
Always print the message "waiting for 10 seconds...", sleep for 10 seconds, and do it again? In other words, do statements in finally clauses run even when the loop is continue-ed?

From the python docs:
When a return, break or continue statement is executed in the try suite of a try...finally statement, the finally clause is also executed ‘on the way out.’ A continue statement is illegal in the finally clause. (The reason is a problem with the current implementation — this restriction may be lifted in the future).

The documentation uses slightly unclear language ("on the way out") to explain how this scenario plays out. If a continue statement is executed inside of an exception clause, the code in the finally clause will be executed and then the loop will continue on to the next iteration.
Here's a very clear example that demonstrates the behavior.
Code:
i=0
while i<5:
try:
assert(i!=3) #Raises an AssertionError if i==3
print("i={0}".format(i))
except:
continue
finally:
i+= 1; #Increment i
'''
Output:
i=0
i=1
i=2
i=4
'''

Now from the latest version of python (3.8.4) , 'continue' can be used inside 'finally' blocks.enter image description here

Related

using break in try/except block doesn't exit loop at the point. why is that?

why does finally section run although I use break in else section
while 1:
try:
print(2)
except:
print("err")
else:
print("we are in else part")
break
finally:
print("we are in finally part")
both else and finally sections run once
shouldn't break exit the while loop at the point?
thanks :)
From the Python tutorial:
If the try statement reaches a break, continue or return statement, the finally clause will execute just prior to the break, continue or return statement’s execution.
This allows the finally clause to ensure that resources are released no matter how the try is exited. For instance, you might put the code to close a file in the finally clause, and it should be executed even if you break out of the loop.
Not too sure if you copy-pasted wrong but you missed an indentation. I tried
while 1:
try:
print(2)
except:
print("err")
else:
print("we are in else part")
break
finally:
print("we are in finally part")
""" (output)
2
we are in else part
we are in finally part
"""
and it worked.

python: try/except/else and continue statement

Why is the output of the below python code snippet NOT just No exception:1, since during first iteration there is no exception raised. From python docs (https://docs.python.org/2.7/tutorial/errors.html).
The try ... except statement has an optional else clause, which, when
present, must follow all except clauses. It is useful for code that
must be executed if the try clause does not raise an exception.
$ cat hello.py
for x in range(1,10):
try:
if x == 1:
continue
x/0
except Exception:
print "Kaput:%s" %(x)
else:
print "No exception:%s" %(x)
break
$ python hello.py
Kaput:2
Kaput:3
Kaput:4
Kaput:5
Kaput:6
Kaput:7
Kaput:8
Kaput:9
$ python -V
Python 2.7.8
The tutorial gives a good start, but is not the language reference. Read the reference here.
Note in particular:
The optional else clause is executed if and when control flows off the end of the try clause.
clarified by footnote 2:
Currently, control “flows off the end” except in the case of an exception or the execution of a return, continue, or break statement.
So your use of continue is explicitly addressed by that.
Your code has a continue, so it never gets to the else block. To achieve your result, you can not get to the continue:
Code:
for x in range(1, 10):
try:
if x != 1:
x / 0
except Exception:
print "Kaput:%s" % (x)
else:
print "No exception:%s" % (x)
break
Result:
No exception:1
It has to do with your use of continue and break. I think this is the functionality you're going for. Basically, continue does not skip to the else statement, it continues on with the code (passed the try statement). And, break breaks the for loop, thus producing no more output, so I removed that statement.
for x in range(1,10):
try:
if x != 1:
x/0
except Exception:
print "Kaput:%s" %(x)
else:
print "No exception:%s" %(x)
This is because of the continue statement... its taking the control to for statement.. try removing the continue and add a conditional statement for x/0, like if(x!=1): x/0 then see the output you desire..

How to stop code execution of for loop from try/except in a Pythonic way?

I've got some Python code as follows:
for emailCredentials in emailCredentialsList:
try:
if not emailCredentials.valid:
emailCredentials.refresh()
except EmailCredentialRefreshError as e:
emailCredentials.active = False
emailCredentials.save()
# HERE I WANT TO STOP THIS ITERATION OF THE FOR LOOP
# SO THAT THE CODE BELOW THIS DOESN'T RUN ANYMORE. BUT HOW?
# a lot more code here that scrapes the email box for interesting information
And as I already commented in the code, if the EmailCredentialRefreshError is thrown I want this iteration of the for loop to stop and move to the next item in the emailCredentialsList. I can't use a break because that would stop the whole loop and it wouldn't cover the other items in the loop. I can of course wrap all the code in the try/except, but I would like to keep them close together so that the code remains readable.
What is the most Pythonic way of solving this?
Try using the continue statement. This continues to the next iteration of the loop.
for emailCredentials in emailCredentialsList:
try:
if not emailCredentials.valid:
emailCredentials.refresh()
except EmailCredentialRefreshError as e:
emailCredentials.active = False
emailCredentials.save()
continue
<more code>

Python - How to stop code from continuing

I have a function that enables and disables services from the Netscaler. I pass in either enable or disable.
However, I want it to exit in the event someone passes a different value. I tried breaking out of it but it tells me my break is outside the loop. How can I resolve this?
def servicegroup_action(servicegroup_name,action):
if not action.upper() in ('ENABLE','DISABLE'):
break
try:
# do stuff
except NSNitroError, e:
print e.message
I think you are looking for return so as to terminate the function execution; a break is used to break out of a loop, and within your current code, there is no associated for/while loop.
The other option is to execute your code only if the correct values are passed, by indenting the try-except within the if block:
def servicegroup_action(servicegroup_name,action):
if action.upper() in ('ENABLE','DISABLE'):
try:
# do stuff
except NSNitroError, e:
print e.message

Handling exceptions from urllib2 and mechanize in Python

I am a novice at using exception handling. I am using the mechanize module to scrape several websites. My program fails frequently because the connection is slow and because the requests timeout. I would like to be able to retry the website (on a timeout, for instance) up to 5 times after 30 second delays between each try.
I looked at this stackoverflow answer and can see how I can handle various exceptions. I also see (although it looks very clumsy) how I can put the try/exception inside a while loop to control the 5 attempts ... but I do not understand how to break out of the loop, or "continue" when the connection is successful and no exception has been thrown.
from mechanize import Browser
import time
b = Browser()
tried=0
while tried < 5:
try:
r=b.open('http://www.google.com/foobar')
except (mechanize.HTTPError,mechanize.URLError) as e:
if isinstance(e,mechanize.HTTPError):
print e.code
tried += 1
sleep(30)
if tried > 4:
exit()
else:
print e.reason.args
tried += 1
sleep(30)
if tried > 4:
exit()
print "How can I get to here after the first successful b.open() attempt????"
I would appreciate advice about (1) how to break out of the loop on a successful open, and (2) how to make the whole block less clumsy/more elegant.
Your first question can be done with break:
while tried < 5:
try:
r=b.open('http://www.google.com/foobar')
break
except #etc...
The real question, however, is do you really want to: this is what is known as "Spaghetti code": if you try to graph execution through the program, it looks like a plate of spaghetti.
The real (imho) problem you are having, is that your logic for exiting the while loop is flawed. Rather than trying to stop after a number of attempts (a condition that never occurs because you're already exiting anyway), loop until you've got a connection:
#imports etc
tried=0
connected = False
while not Connected:
try:
r = b.open('http://www.google.com/foobar')
connected = true # if line above fails, this is never executed
except mechanize.HTTPError as e:
print e.code
tried += 1
if tried > 4:
exit()
sleep(30)
except mechanize.URLError as e:
print e.reason.args
tried += 1
if tried > 4:
exit()
sleep(30)
#Do stuff
You don't have to repeat things in the except block that you do in either case.
from mechanize import Browser
import time
b = Browser()
tried=0
while True:
try:
r=b.open('http://www.google.com/foobar')
except (mechanize.HTTPError,mechanize.URLError) as e:
tried += 1
if isinstance(e,mechanize.HTTPError):
print e.code
else:
print e.reason.args
if tried > 4:
exit()
sleep(30)
continue
break
Also, you may be able to use while not r: depending on what Browser.open returns.
Edit: roadierich showed a more elegant way with
try:
doSomething()
break
except:
...
Because an error skips to the except block.
For your first question, you simply want the "break" keyword, which breaks out of a loop.
For the second question, you can have several "except" clauses for one "try", for different kinds of exceptions. This replaces your isinstance() check and will make your code cleaner.

Categories