understanding "try" and "except" python - python

For what I have understand till now is, computer will try to run the code in try section and will except stuff mentioned in except part. As soon as computer got something as mentioned in except it will run except code.
So, I tried the following:
try:
if year // 100:
print year, "is not a leap year"
else:
print year, "is not a leap year"
except year // 400 and year // 4:
print "is a leap year"
This does not work.
I want to know why it is so?

Please, read the doc.
The try statement works as follows.
First, the try clause (the statement(s) between the try and except keywords) is executed.
If no exception occurs, the except clause is skipped and execution of the try statement is finished.
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.
If an exception occurs which does not match the exception named in the except clause, it is passed on to outer try statements; if no
handler is found, it is an unhandled exception and execution stops
with a message as shown above.

basically a try and except is like an if and else...kinda
except that when you try if it doesn't raise an exception it excecutes the try code block but when it fails it'll execute the except block for example
a = [1,2,3,4,"hello"]
for i in a:
try:
print(i)
i + 1
except:
print("nope " + i + " is a string")

Related

Difference between bare except and specifying a specific exception

In this piece of code, I could write a simple except clause without writing Exception in front of it. I mean the last line could be like this :
except:
print('Hit an exception other than KeyError or NameError!')
What is the point of writing Exception in front of an except clause ?
try:
discounted_price(instrument, discount)
except KeyError:
print("There is a keyerror in your code")
except NameError:
print('There is a TypeError in your code')
except Exception:
print('an exception occured')
I tried writing an except clause without Exception keyword and it worked the same.
Thank you guys for your answers . I know the point of catching specific errors. If I want to ask more clearly , what is the difference between two clauses :
except Exception:
print('an exception occured')
except :
print('an exception occured')
The point of specifying the Exception is that ONLY that Exception will be caught, if you do not specify any Exception, then ALL Errors and Exceptions will be caught potentially masking bugs.
For example let's say that I want to read a file if it exists or otherwise print a message to the user, I can write:
try:
with ope("example.txt", "r") as f:
print(f.read())
except:
print("File not found")
But while this code runs fine without raising any exceptions, this code will never read the file, even if it exists!!!
This is because I wrote ope instead of open and the NameError was caught by my bare except, If I write the except in the correct way:
try:
with ope("example.txt", "r") as f:
print(f.read())
except FileNotFoundError:
print("File not found")
Now I can properly debug my code:
Traceback (most recent call last):
File "/home/riccardo/types.py", line 4, in <module>
with ope("example.txt", "r") as f:
NameError: name 'ope' is not defined
A bare expect
try:
...
except:
pass
or catching any exception whatsoever
try:
...
except Exception:
pass
are bad practice, because you can be hiding bug or be interfering with the normal procedure of the program.
You should only catch exception that you know how to handle, everything else you should let it propagate.
For some example:
Hide bug: it can hide some typo in your code as Caridorc example show making you think that you had a problem different than the real problem
Interfering with the normal procedure: you can make it an unexpectedly unkillable program or get in the way of the normal procedure of the program by discarding an exception that another part of the code was expecting.
like for example
while True:
try:
print("running")
except:
print("I'm immortal muahahaha")
this piece of code now you can't stop with you usual control-z (control-z throw and KeyboardInterrupt exception into your program) so you now need to close the whole interpreter/kill it with the task admin just to stop it, and if this was unintended you just introduced a new bug and depending on what you're doing it can be catastrophic.
To illustrate how catastrophic it can be, consider the following hypothetical case: imagine you make so benign function for a medical device and you put something like this
try:
...
except:
print("some error happens")
now it just so happens that while you piece of code was running a HeartAttack exception was raised and your catch it all and ignore piece of code will do, well, just that, and here is the twist this device was a pacemaker... well, congratulation you just killed the poor guy.
And that is why you should only catch the exception you know how to deal with, everything else you let it pass and hope that somebody along the line know how to deal with it, like in the example above, you and your piece of code don't know how to deal with a HeartAttack, but the pacemaker do and the pacemaker was the one that call your piece of code let it deal with it...
for a no so extreme example consider this simple code
def get_number_from_user():
while True:
try:
return int(input("write a number: "))
except:
print("not a valid number try again")
if your user was done with your program and this happens to be the thing running he/she might want to kill it with a control-z as you usually do with any program, but it will find that it doesn't work, the correct way here is to catch the error we know how to deal with in this case, namely ValueError, everything else isn't this function business
def get_number_from_user():
while True:
try:
return int(input("write a number: "))
except ValueError:
print("not a valid number try again")
You also ask about the difference between
try:
...
except:
pass
and this
try:
...
except Exception:
pass
the difference is that a bare except can catch any and all kind of exception, that in python is anything that is or inherit from BaseException that sit at the top of the exception hierarchy, while except Exception will catch only Exception itself or anything that inherit from it (the same apply for any particular exception you put there), this small distinction allow to make some exceptions more special than other, like the aforementioned KeyboardInterrupt that inherit from BaseException instead of Exception, and that is used to signal that the user wants to terminate this program, so you should do so and this distinction is made basically so new programmers don't shoot themselves in the foot when using except Exception
Just to add to the answer provided by #Caridorc, by specifying each error separately, you can run specific error handling code pertaining to that error when the exception arises. If for example the file does not exist, you can print message to that effect. If however, it fails to print because you mistyped g instead of f, you can print a message to say that the variable is not recognised ( separate code for separate error captures). For exmple:
g = 100 # Unrelated variable declared previously
try:
with open("example.txt", "r") as f:
x=print(f.read())
except FileNotFoundError:
print("File not found")
except AttributeError:
print("Reading wrong variable")
except Exception as e:
print("Unknown Error", e)
Note also the last exception except Exception as e:. This is the same as just except: but allows you to handle all other errors that do not fit onto previous captures and retrieve e - the error message that is generated by compiler. There is effectively no difference between except: and except Exception: in terms of execution
Consider the code:
a = 5
b = 0
x = a / b
Executing this will alert you to the fact that you have attempted to divide a float by zero but it will crash your code.
Now consider:
a = 5
b = 0
try:
x = a / b
except: # or 'except Exception:'
print("An exception was raised")
This will raise an exception that is handled by printing a message that an error occurred. You code will not crash but you do not know how to properly handle the code because you do not know what the exception was, just that one occurred.
Now consider:
a = 5
b = 0
try:
x = a / b
except Exception as e:
print("An exception was raised, generating error", e)
Now your code does not crash. Is handled and you know what the error was.
The purpose of writing "Exception" in front of an except clause is to catch all possible exceptions that can occur in the code. By specifying "Exception", you are telling the interpreter to handle any type of exception that might be raised. The more specific the exception specified in the except clause, the more targeted the handling of the exception can be. For example, if you only want to handle "KeyError" exceptions, you can specify that explicitly in the except clause, as in the first example.

When would I use 'else' and 'finally' in a try-except statement in python? [duplicate]

This question already has answers here:
What is the intended use of the optional "else" clause of the "try" statement in Python?
(22 answers)
Closed last year.
My question is where the difference between
try:
print("Hello")
except:
print("Something went wrong")
else:
print("Nothing went wrong")
and
try:
print("Hello")
print("Nothing went wrong")
except:
print("Something went wrong")
lies. The result seems identical to me. What are use cases to use the else statement?
Similarly, why would I ever use the finally statement?
try:
print(x) #Not defined before
except:
print("Something went wrong")
finally:
print("The 'try except' is finished")
and
try:
print(x) #Not defined before
except:
print("Something went wrong")
print("The 'try except' is finished")
again seems identical.
Edit:
I do know, what 'else' and 'finally' do. I just don't know when to use them as it seems you can reach an equivalent result without these statements.
The else block is only executes when no exception got raised. So
try:
f_noexception()
print("hello")
except Exception
pass
else:
print("Hello again")
Should give you two prints. Personallz, I think this is mildly useful and you actually don't see it being used very often.
However, finally is much more useful. The finally block gets always executed no matter if an exception was raised or not. So you can use that for doing some clean ups for example. Especially when you don't just catch an exception and handle it, but want it to get raised.
Answering to your 1st question:
Let's suppose there is an exception in your try block may be between these 2 lines
1.print("Hello")
2.print("Nothing went wrong")
In that case the second line will not be printed and the control will go to except block,so the output would not be the same.
The answers are same as there is no exception in your codes
So, when you have a code in which an exception might occur and you want something to get executed if that exception doesn't occur write it in else block.
Now answering to your 2nd question:
Finally is used when you want something to execute even if an exception occurs in try block.
Again your output are same because there is no exception in your try blocks.Try raising an exception and see the difference yourself.
finally keyword in Python
finally block is always executed after leaving the try statement. In case if some exception was not handled by except block, it is re-raised after execution of finally block.
finally block is used to deallocate the system resources.
One can use finally just after try without using except block, but no
exception is handled in that case.
finally block is executed regardless of exception is handled or not.
try:
print(x) #Not defined before
except:
print("Something went wrong")
finally:
#this block is always executed
# regardless of exception generation.
print('This is always executed')
Here, if your except block executes or not, finally block is always executed.

Why does try exits after first statement if it throws an Exception?

I am new to python I am learning exception handling now.
try:
print(1/0)
int(input("number"))
import bala
except ZeroDivisionError:
print("Divided by zero")
except KeyboardInterrupt:
print("dont press ctrl C!")
except ValueError:
print("Value should be number")
except ModuleNotFoundError:
print("Module not found")
The above code exits after first exception and the rest of the try statements are not executed. Should I use separate try-except block for each statement? Like this
try:
int(input("number"))
except ValueError:
print("Value should be number")
and
try:
import bala
except ModuleNotFoundError:
print("Module not found")
If an exception is raised that makes Python stop the execution immediately. You can prevent a complete program stop by using a try and except. However if an exception is raised in the try block, it will still stop execution right there and only continue if an appropriate except block catches the Exception (or if there is a finally block).
In short: If you want to continue with the next statements you need to use separate try and except blocks. But if you want to execute the next statements only if the previous statements didn't raise an Exception you shouldn't use separate try and except blocks.
Yes you need to have separate exception blocks because if it gets by the first block, it thinks thats all it needs to get by, so if you want to test every one, you should use separate ones
You have to use multiple try/except blocks.
Once an error is found, anything happening is stopped, and the exception is dealed with.
Think of it as a fire. When there is a fire you stop whatever and run out. For python it deals with the exception

Try if Statement Breaks my print str

I'm trying to make it so if the user enters in any letters it won't give any errors. It will just restart the program.
x = int(input())
try:
if x == (a, b, c): # Entering letters in the x integer will restart the program.
displayStart()
return
print('')
I have this, The print statement at the bottom becomes an invalid syntax after i've entered this "try:" Statement. Any suggestions on how to fix it?
try suites need to have an except and/or finally clause. You have neither. e.g.
try:
do_something()
except SomeExceptionName:
do_something_because_some_exception_name_was_raised_in_do_something()
Or:
try:
do_something()
finally:
do_something_even_if_exception_was_raised()
You also might want to have a look at the python tutorial.
If you think about it, what should your try suite do here? If an exception is raised, what would happen differently than normal if you have no way of handling it (via except) or cleanup action to perform (via finally)?
From the python grammer specification:
try_stmt: ('try' ':' suite
((except_clause ':' suite)+
['else' ':' suite]
['finally' ':' suite] |
'finally' ':' suite))
This is an example of a try statement:
try:
print("this will actually print, because its trying to execute the statements in the tryblock")
assert(1==0) #a blatently false statement that will throw exception
print("This will never print, because once it gets to the assert statement, it will throw an exception")
except:
print("after exception this is printed , because the assert line threw an exception")
IF the assert sttement had been assert(1==1) it would have never thrown an exception, then it would have printed the "This will never print" line, and NOT the "after exception" line
Of course there are more things involved like finally and else, but this try: except: example should be enough to get you started
You need to add an except portion to your try statement. Like this:
x = int(input())
try:
if x == (a, b, c):
displayStart()
return
except Exception as e:
print('An exception occurred: ', e)
print('')
A try needs to have its corresponding except.
As a note, it is not very good practice to catch ALL exceptions like I do. Instead of Exception, usually you would specify the particular exception you expect. For example, if I am expecting a ValueError, I would make it:
try:
...
except ValueError as ve:
print('A Value Error occurred: ', ve)
Also, you usually want to put as little code in the try-except block as possible.

How to see the error and still keep the program on in the Python shell?

I know try/except can handle errors in my program.
But, is there a way of making the error be displayed in the program execution, be ignored and let the execution go on?
In VBScript and other VB-derived languages, you can get this sort of behavior with "ON ERROR GOTO NEXT".
No such behavior exists in Python. Even if you wrap each top-level statement like:
try:
do_something()
except Exception as e:
print e
try:
do_something_else()
except Exception as e:
print e
you'd still have the result that statements within do_something are skipped at the point the exception is thrown.
Though perhaps if you have a particular use-case in mind, there may be other acceptable answers. For instance, in a top-level loop:
while True:
cmd = get_command()
if cmd == 'quit': break
try:
run_command(cmd)
except Exception as e:
print "Error running " + cmd + ":"
print e
import traceback
try:
# do whatever you want
except Exception:
traceback.print_exc()
Of course you should be more specific in a real scenario, i.e. you shouldn't catch and ignore all Exception instances, only the ones you are interested in and you know that they are safe to ignore.
Also note that if an exception happens somewhere within the try..except block, the execution will continue after the try..except block, not at the next statement. This is probably the closest to what you want to achieve.

Categories