What's the scope of using the 'finally' clause in python? [duplicate] - python

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Purpose of else and finally in exception handling
I'd like to understand why the finally clause exists in the try/except statement. I understand what it does, but clearly I'm missing something if it deserves a place in the language. Concretely, what's the difference between writing a clause in the finally field with respect of writing it outside the try/except statement?

The finally suite is guaranteed to be executed, whatever happens in the try suite.
Use it to clean up files, database connections, etc:
try:
file = open('frobnaz.txt', 'w')
raise ValueError
finally:
file.close()
os.path.remove('frobnaz.txt')
This is true regardless of whether an exception handler (except suite) catches the exception or not, or if there is a return statement in your code:
def foobar():
try:
return
finally:
print "finally is executed before we return!"
Using a try/finally statement in a loop, then breaking out of the loop with either continue or break would, again, execute the finally suite. It is guaranteed to be executed in all cases.

The finally clause will always execute which is great if you missed an exception type in your code.
To quote the documentation:
If finally is present, it specifies a ‘cleanup’ handler. The try clause is executed, including any except and else clauses. If an exception occurs in any of the clauses and is not handled, the exception is temporarily saved. The finally clause is executed. If there is a saved exception, it is re-raised at the end of the finally clause. If the finally clause raises another exception or executes a return or break statement, the saved exception is lost. The exception information is not available to the program during execution of the finally clause.

Related

Python try except

try:
#statement 1
#statement 2
except Exception, err:
print err
pass
This may be very trivial but I never actually thought about it until now and I found myself not being able to answer the following questions:
Does statement 2 gets executed if an error is raised in statement 1?
How does Exception deal with in a case where an error is raised for both statement 1 and statement 2? Which error does it print out in the above code? Both?
The answer is "no" to both of your questions.
As soon as an error is thrown in a try/except block, the try part is immediately exited:
>>> try:
... 1/0
... print 'hi'
... except ZeroDivisionError, e:
... print 'error'
...
error
>>>
As you can see, the code never gets to the print 'hi' part, even though I made an except for it.
You can read more here.
From Python docs:
If an exception occurs during execution of the try clause, the rest of
the clause is skipped. Then if its type matches the exception named
after the except keyword, the except clause is executed, and then
execution continues after the try statement.
So as soon as an error occurs, it skips to the exception
http://docs.python.org/2/tutorial/errors.html
Upon an exception being raised control leaves the try block at the point the exception is raised and is given to the appropriate except block. If statement 1 throws an exception, statement 2 will not execute.
This answers your second question as well: it's not possible for the scenario you describe to happen.
1) Does statement 2 gets executed if an error is raised in statement 1?
No. Exception will be raised and catched.
As I understand python will move up the stack and looks for an exception handler in the caller
2) How does Exception deal with in a case where an error is raised for both statement 1 and statement 2? Which error does it print out in the above code? both?
statement 2 will not be run so no exceptions will be raised for it
any exception from the try block will be caught. That is why for all try/except clauses, limit the try clause to the absolute minimum amount of code necessary. Again, this avoids masking bugs.
1) Does statement 2 gets executed if an error is raised in statement
1?
nope, statement 2 is not executed
2) How does Exception deal with in a case where an error is raised for
both statement 1 and statement 2? Which error does it print out in the
above code? both?
only statement 1 has a chance to raise an error, see above,
NOTE: if you want statement 2 to execute always, you can use finally with the try/except

Why use else in try/except construct in Python?

I am learning Python and have stumbled upon a concept I can't readily digest: the optional else block within the try construct.
According to the documentation:
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.
What I am confused about is why have the code that must be executed if the try clause does not raise an exception within the try construct -- why not simply have it follow the try/except at the same indentation level? I think it would simplify the options for exception handling. Or another way to ask would be what the code that is in the else block would do that would not be done if it were simply following the try statement, independent of it. Maybe I am missing something, do enlighten me.
This question is somewhat similar to this one but I could not find there what I am looking for.
The else block is only executed if the code in the try doesn't raise an exception; if you put the code outside of the else block, it'd happen regardless of exceptions. Also, it happens before the finally, which is generally important.
This is generally useful when you have a brief setup or verification section that may error, followed by a block where you use the resources you set up in which you don't want to hide errors. You can't put the code in the try because errors may go to except clauses when you want them to propagate. You can't put it outside of the construct, because the resources definitely aren't available there, either because setup failed or because the finally tore everything down. Thus, you have an else block.
One use case can be to prevent users from defining a flag variable to check whether any exception was raised or not(as we do in for-else loop).
A simple example:
lis = range(100)
ind = 50
try:
lis[ind]
except:
pass
else:
#Run this statement only if the exception was not raised
print "The index was okay:",ind
ind = 101
try:
lis[ind]
except:
pass
print "The index was okay:",ind # this gets executes regardless of the exception
# This one is similar to the first example, but a `flag` variable
# is required to check whether the exception was raised or not.
ind = 10
try:
print lis[ind]
flag = True
except:
pass
if flag:
print "The index was okay:",ind
Output:
The index was okay: 50
The index was okay: 101
The index was okay: 10

Stop Python code without an error

I have a piece of code which is not in a function, say
x = 5
y = 10
if x > 5:
print("stopping")
What can I put after the print statement to stop the code from running further? Sys.exit() works, but raises an error that I don't want in the program. I want it to quietly stop the code as if it had reached the end of the main loop. Thanks.
As JBernardo pointed out, sys.exit() raises an exception. This exception is SystemExit. When it is not handled by the user code, the interpreter exits cleanly (a debugger debugging the program can catch it and keep control of the program, thanks to this mechanism, for instance)—as opposed to os._exit(), which is an unconditional abortion of the program.
This exception is not caught by except Exception:, because SystemExit does not inherit from Exception. However, it is caught by a naked except: clause.
So, if your program sees an exception, you may want to catch fewer exceptions by using except Exception: instead of except:. That said, catching all exceptions is discouraged, because this might hide real problems, so avoid it if you can, by making the except clause (if any) more specific.
My understanding of why this SystemExit exception mechanism is useful is that the user code goes through any finally clause after a sys.exit() found in an except clause: files can be closed cleanly, etc.; then the interpreter catches any SystemExit that was not caught by the user and exits for good (a debugger would instead catch it so as to keep the interpreter running and obtain information about the program that exited).
You can do what you're looking for by doing this:
import os
os._exit(1)
sys.exit() which is equivalent to sys.exit(0) means exit with success. sys.exit(1) or sys.exit("Some message") means exit with failure. Both cases raise a SystemExit exception. In fact when your program exists normally it is exactly like sys.exit(0) has been called.
When I ran across this thread, I was looking for a way to exit the program without an error, without an exception, have the code show as 'PASSED', and continue running other tests files. The solution, for me, was to use the return statement.
.
.
.
if re.match("^[\s\S]*gdm-simple-slave[\s\S]*$", driver.find_element_by_css_selector("BODY").text) == None:
print "Identifiers object gdm-simple-slave not listed in table"
return
else:
driver.find_element_by_xpath("//input[#value='gdm-simple-slave']").click()
.
.
.
That allowed me to run multiple programs while keeping the debugger running...
test_logsIdentifiersApache2EventWindow.py#16::test_LogsIdentifiersApache2EventWi
ndow **PASSED**
test_logsIdentifiersAudispdEventWindow.py#16::test_LogsIdentifiersAudispdEventWi
ndow **PASSED**
test_logsIdentifiersGdmSimpleSlaveEventWindow.py#16::test_LogsIdentifiersGdmSimp
leSlaveEventWindow Identifiers object gdm-simple-slave not listed in table
**PASSED**
test_logsIdentifiersAuditdEventWindow.py#16::test_LogsIdentifiersAuditdEventWind
ow **PASSED**
Use try-except statements.
a = [1, 2, 3, 4, 5]
for x in xrange(0,5):
try:
print a[x+1] #this is a faulty statement for test purposes
except:
exit()
print "This is the end of the program."
Output:
> python test.py
2
3
4
5
No errors printed, despite the error raised.

Preventing python definition from execution

I want to know what is the best way of checking an condition in Python definition and prevent it from further execution if condition is not satisfied. Right now i am following the below mentioned scheme but it actually prints the whole trace stack. I want it to print only an error message and do not execute the rest of code. Is there any other cleaner solution for doing it.
def Mydef(n1,n2):
if (n1>n2):
raise ValueError("Arg1 should be less than Arg2)
# Some Code
Mydef(2,1)
That is what exceptions are created for. Your scheme of raising exception is good in general; you just need to add some code to catch it and process it
try:
Mydef(2,1)
except ValueError, e:
# Do some stuff when exception is raised, e.message will contain your message
In this case, execution of Mydef stops when it encounters raise ValueError line of code, and goes to the code block under except.
You can read more about exceptions processing in the documentation.
If you don't want to deal with exceptions processing, you can gracefully stop function to execute further code with return statement.
def Mydef(n1,n2):
if (n1>n2):
return
def Mydef(n1,n2):
if (n1>n2):
print "Arg1 should be less than Arg2"
return None
# Some Code
Mydef(2,1)
Functions stop executing when they reach to return statement or they run the until the end of definition. You should read about flow control in general (not specifically to python)

Try-Except Behavior

import sys
def checkarg():
try:
filename=str(sys.argv[1])
if filename=="-mycommand":
print "SPECIFIC_TEXT"
sys.exit()
else:
return filename
except:
print "ERROR"
sys.exit()
Hello all...i have a problem with the code above. When i call the 'checkarg' function, if i did not pass any parameter on the command line i have the "ERROR" output and sys exit, just as expected.
But, if i provide a parameter on the command line (like "-mycommand") it prints the "SPECIFIC_TEXT" and then prints "ERROR" message from the EXCEPT block too.
The TRY block will only run when I provide a parameter, if I don't, then EXCEPT will get the turn. But, it is running the TRY and EXCEPT blocks together.
Does anybody knows the reason of this behavior?? Any mistake on my code? Tks for all !
I think I understand your question...
sys.exit() exits by raising a SystemExit exception, which your except statement is catching.
Answer found here: http://docs.python.org/library/sys.html
sys.exit([arg])
Exit from Python. This is implemented by raising the SystemExit exception, so cleanup actions specified by finally clauses of try statements are honored, and it is possible to intercept the exit attempt at an outer level.
sys.exit works by raising an exception. That's why your except block executes.
You really shouldn't be using try/except for situations where you can check the state using control flow logic.
Instead, in this case, check for if len(sys.argv) > 1.
Another reason never to use specifically a blank except: You will catch even system exceptions like SystemExit or KeyboardInterrupt, making it potentially impossible to terminate your program short of a messy kill.
I know you've already accepted an answer, but I think the root of the problem is that your try block contains code in which you do not necessarily wish to catch exceptions; rather, you merely wish these statements to be executed after the code in which you wish to catch exceptions if no exception occurs.
To address this, your try block should contain only filename=str(sys.argv[1]) and the rest of the code now in your try block should be moved to an else block, which will be executed only if no exception occurs. In other words:
try:
filename=str(sys.argv[1])
except:
print "ERROR"
sys.exit()
else:
if filename=="-mycommand":
print "SPECIFIC_TEXT"
sys.exit()
else:
return filename
Or in this case, since you exit the script entirely in the case of an exception, you don't actually need the else:
try:
filename=str(sys.argv[1])
except:
print "ERROR"
sys.exit()
if filename=="-mycommand":
print "SPECIFIC_TEXT"
sys.exit()
else:
return filename
The fact that you're catching every exception with your bare except is bad style and changing that would also avoid the problem, but to me, it's secondary. You do not wish to catch exceptions in your if/else code, so it should not be in the try block to begin with. IMHO, most admonitions against bare except would be moot if this guideline were followed more closely.

Categories

Resources