I am teaching myself python and I am still an amateur at remembering all the keywords.
So; simple question, is there to way to use an if statement for an exception?
I can make the exception(NameError) print something. However, I want to use an if statement for if the exception is executed, then do this.
Help would be greatly appreciated!
try-except blocks were designed specifically for the purpose of catching exceptions. if statements are conditionals and are not designed to work with exceptions.
Here's a simple program to demonstrate exception handling:
class SomeException(Exception):
pass
try:
print("In try block.")
raise SomeException()
except SomeException:
print("In except block.")
Additionally, if you need information about the exception, you can use a special except block:
class SomeException(Exception):
pass
try:
print("In try block.")
raise SomeException()
except SomeException as exc: #exc is the exception object
print("In except block.")
When creating exceptions, you can optionally pass one or more arguments to indicate why the exception was raised:
class SomeException(Exception):
pass
try:
print("In try block.")
raise SomeException("message")
except SomeException as exc:
print(exc.args[0]) #Prints "message"
Here's a tutorial on exceptions that I found particularly useful.
A "try-except" block is exactly what you're looking for. Any code in the "try" part is executed normally, but if there's an exception, instead of returning back, it goes to the "except" block.
To phrase it how you were asking, any code in an "except" block runs IF the specific exception was raised/excecuted.
Instead of an error like this:
print(x)
NameError: name 'x' is not defined
You could do this:
try:
print(x)
except NameError:
print("error!")
error!
It will print "error!" IF anything in the try: block resulted in a NameError.
You can also use "else" and "finally" for more control.
Any code in the Else block runs if there were no errors.
try:
print("Hello")
except:
print("Something went wrong")
else:
print("Nothing went wrong")
Hello
Nothing went wrong
Anything in a "finally" block runs after regardless of if there was an error or not.
try:
print(x)
except:
print("Something went wrong")
finally:
print("The 'try except' is finished")
Something went wrong
The 'try except' is finished
I recommend reading the W3 Schools page on Try Except.
https://www.w3schools.com/python/python_try_except.asp
Protip: you can do something like except Exception as e which will save info about the exception to e.
Related
I have a try/except block with multiple except blocks. I want to be able to execute a piece of code only if any of the exceptions are raised. Kind of like the finally statement, but finally execute regardless of if an exception was raised or not. Do I just have to add that code to each except block?
You can do your own type checking in the exception handler to deal with type-specific and general code.
def it_will_end_in_tears():
raise ValueError("bad value")
try:
val = it_will_end_in_tears()
except (TypeError, ValueError) as e:
if isinstance(e, TypeError):
print("type error stuff")
elif isinstance(e, ValueError):
print("value error stuff")
print("common stuff")
finally:
print("finally")
Instead of copy+pasting the code into each except block, i would declare a boolean execute_code = False and set it to True in each of the except blocks. After the whole try/except, add if execute_code:, then implement the code to execute if an exception occurred once inside the if block.
Hi im currently doing a program like this.
class MyError(Exception):
def __init__(self, text = "Correct")
self.text = text
def __str__(self):
return (self.kod)
class Atom(self):
.
.
.
try:
function()
else:
raise MyError("Incorrect use of function")
def main():
try:
a = Atom()
except:
# Here i want to print the error that was raised
What I think I understand is that the error is raised in an object created in Atom().
But I want to send it to my main program and do the print of the error MyError there.
Is it possible to do this and how should I write it so that the correct text of exception is printed since i will have several different error messages.
If i come to the except statement I would want to get the message "Incorrect use of function" printed.
It seems that you're pretty close:
class MyError(Exception):
def __init__(self, text = "Correct")
self.text = text
def __str__(self):
return (self.kod)
class Atom(self):
.
.
.
try:
function()
except: # try: ... else: raise ... seems a bit funky to me.
raise MyError("Incorrect use of function")
def main():
try:
a = Atom()
except Exception as err: # Possibly `except MyError as err` to be more specific
print err
The trick is that when you catch the error, you want to bind the exception instance to a name using the as clause. Then you can print it, look at it's attributes, re-raise or pretty much do anything you choose with it.
Please note that this code still isn't "clean". Generally, you want to limit exception handling as much as possible -- only catch exceptions that expect to see and that you know how to handle. Otherwise, you can sometimes mask hard to find bugs in your code. Because of this:
try:
do_something()
except:
...
is discouraged (it catches all sorts of things like KeyboardInterrupt and SystemExit) ... Instead:
try:
do_something()
except ExceptionIKnowHowToHandle:
...
is advised.
Firstly, never do a blank except. That will catch all errors, including things like KeyboardInterrupt - so you won't be able to ctrl-c out of your program. Here you should just catch MyError.
The except clause also allows you to assign the actual exception to a variable, which you can then print or do anything else with. So you can do:
try:
...
except MyError as e:
print e.text
I have to deal with a large quantity of try/except. I'm in doubt about the right way of doing it.
Option 1:
inst = Some(param1, param2)
try:
is_valid = retry_func(partial(inst.some_other), max_retry=1)
except RetryException, e:
SendMail.is_valid_problem(e)
if is_valid:
print "continue to write your code"
...
*** more code with try/except ***
...
Option 2:
inst = Some(param1, param2)
try:
is_valid = retry_func(partial(inst.some_other), max_retry=1)
if is_valid:
print "continue to write your code"
...
*** more code with try/except ***
...
except RetryException, e:
SendMail.is_valid_problem(e)
In the Option 1, even is the exception is raised, "is_valid" will be tested and I don't need that.
In the Option 2, is what I think is correct but the code will look like a "callback hell".
What option should I choose or what option is the correct one?
Keep your exception handling as close as possible to the code that raises the exception. You don't want to accidentally mask a different problem in code you thought would not raise the same exception.
There is a third option here, use the else: suite of the try statement:
inst = Some(param1, param2)
try:
is_valid = retry_func(partial(inst.some_other), max_retry=1)
except RetryException, e:
SendMail.is_valid_problem(e)
else:
if is_valid:
print "continue to write your code"
...
*** more code with try/except ***
...
The else: suite is only executed if there was no exception raised in the try suite.
From your conditions, condition 1 is better and you can use else instead of if is_valid
Here are some of Try Except:
Here is simple syntax of try....except...else blocks:
try:
You do your operations here;
......................
except ExceptionI:
If there is ExceptionI, then execute this block.
except ExceptionII:
If there is ExceptionII, then execute this block.
......................
else:
If there is no exception then execute this block.
The except clause with multiple exceptions:
try:
You do your operations here;
......................
except(Exception1[, Exception2[,...ExceptionN]]]):
If there is any exception from the given exception list,
then execute this block.
......................
else:
If there is no exception then execute this block.
The try-finally clause:
try:
You do your operations here;
......................
Due to any exception, this may be skipped.
finally:
This would always be executed.
I think option 1 is better. The reason is that you should always put inside a try except only the code which you expect to throw the exception. Putting more code increase the risk of catching an unwanted exception.
Make sure that if an Error will occur, keep the cause inside the try statement. That way, it will catch the error and sort it out in the except section. There is also finally. If the try doesn't work, but the "except" error doesn't work, it will act out the "finally" statement. If there is no finally, the program will get stuck. This is a sample code with try and except:
import sys
import math
while True:
x=sys.stdin.readline()
x=float(x)
try:
x=math.sqrt(x)
y=int(x)
if x!=y:
print("Your number is not a square number.")
elif x==y:
print("Your number is a square number.")
except(ValueError):
print("Your number is negative.")
ValueError is the error you get from sqrt-ing a negative number.
I have:
try:
...
except Exception, e:
print "Problem. %s" % str(e)
However, somewhere in try, i will need it to behave as if it encountered an Exception. Is it un-pythonic to do:
try:
...
raise Exception, 'Type 1 error'
...
except Exception, e:
print "Problem. Type 2 error %s" % str(e)
I think this is a bad design. If you need to take some action if (and only if) an exception wasn't raised, that is what the else clause is there for. If you need to take some action unconditionally, that's what finally is for. here's a demonstration:
def myraise(arg):
try:
if arg:
raise ValueError('arg is True')
except ValueError as e:
print(e)
else:
print('arg is False')
finally:
print("see this no matter what")
myraise(1)
myraise(0)
You need to factor the unconditional code into finally and put the other stuff in except/else as appropriate.
I think what you are doing is "unPythonic". Trys should really only cover the small part (ideally one line) of the code which you expect might sometimes fail in a certain way. You should be able to use try/except/else/finally to get the required behaviour:
try:
#line which might fail
except ExceptionType: # the exception type which you are worried about
#what to do if it raises the exception
else:
#this gets done if try is successful
finally:
#this gets done last in both cases (try successful or not)
I have code:
try:
print test.qwerq]
try:
print test.sdqwe]
except:
pass
except:
pass
How to print debug info for all errors in nested try ?
Re-raise exceptions.
try:
print test[qwerq]
try:
print test[qwe]
except:
# Do something with the exception.
raise
except:
# Do something here too, just for fun.
raise
It should be noted that in general you don't want to do this. You're better off not catching the exception if you're not going to do anything about it.
If you want to just print the call stack and not crash, look into the traceback module.