I'm writing a utility module and trying to make it as generic as possible, and I'm trying to work out what the behavior would be here:
for i in xrange(num_tries):
try:
return func(*args, **kwards)
except exceptions as e:
continue
I understand that
except:
Will catch ALL exceptions, and that
except (some, tuple, of, exceptions) as e:
Will catch those 4 exceptions,
But what is the behavior of an empty tuple? Does it simply catch
No exceptions
All exceptions
My guess is 1, but I can't think of quick way to test it. My thinking is that except with no parameters after would be except None, but an empty tuple would just be like saying "catch everything in this list", but there's nothing in the list so nothing is caught.
Thanks!
The answer is 1: no exceptions, in Python 2 and in Python 3.
exceptions = ()
try:
a = 1 / 0
except exceptions as e:
print ("the answer is 2")
Traceback (most recent call last): File "<pyshell#38>", line 2, in <module>
a = 1 / 0
ZeroDivisionError: integer division or modulo by zero
If you want to the behaviour of answer 2 when the list of exceptions is empty, you can do
except exceptions or (Exception,) as e:
Related
I have a try block case in my code and I want to ignore one particular exception and all the rest should be raised.
For example:
try:
blah
except <exception> as e:
raise Exception(e)
In this kind of case, I want all the exceptions to be raised except for one case, say if the exception is "query not found" I have to ignore it.
How do I ignore that single exception?
I can use multiple except blocks but how to define a exception?
You can give something like this:
try:
print(x)
except NameError:
print("Variable x is not defined")
except:
print("Something else went wrong")
In this case, you want to catch NameError and specify a message. For all others, you want to specify another message.
Let's say you want to ignore NameError, then you can just give continue or pass.
Alternatively, you can also raise an exception.
Example will be:
x = -1
if x < 0:
raise Exception("Sorry, no numbers below zero")
So you can use a combination of all this to get you what you want.
If you want more details on exception, see the below links:
https://docs.python.org/3/tutorial/errors.html
https://www.w3schools.com/python/python_try_except.asp
https://realpython.com/python-exceptions/
And on stack overflow (as Gino highlighted), see
Handling all but one exception
As an alternative to #Joe Ferndz's answer, in case you don't want the exception to be raised but still want the block to exit, you can use suppress from the contextlib module:
from contextlib import suppress
with suppress(ValueError):
print('hello world')
raise ValueError
print('this will not be printed')
In this case, the block still exits on raise ValueError, but an exception is not raised.
Recently I met an example of code I've never seen before:
try:
# a simple bunch of code
if sample == 0:
return True
else:
raise ExampleError()
except not ExampleError:
raise AnotherExampleError()
How does it work (if it works at all)?
EDIT: The answer below was for Python 3, I didn't realise the question related to Python 2.7. in Python 2, as it seems, the interpreter does not complain if the expression after except does not result in a subtype of BaseException. However, the behavior is still wrong, it will just ignore that except block in all cases.
That's a funny construction that is syntactically valid but semantically wrong. I suppose the author of the code meant to express something like "run this except block for any exception type but ExampleError". However, what is really happening is more like:
try:
# ...
except (not bool(ExampleError)):
# ...
When an exception is raised in the try block, Python goes through the different except blocks looking for one that matches the exception type. When it sees except not ExampleError, equivalent to except (not bool(ExampleError)), it results in except False, which is invalid because False is not a subtype of BaseException (or a tuple of subtypes of BaseException). So the code may even run if no exceptions are raised but is wrong.
This is not going to be successful on any version of Python as far as I know. Because the not operator always results in a Boolean value (True or False) this is trying to catch one of those values here, in this case False. Since you can't throw True or False there's no use for this.
I think the intent of the author was something like this:
try:
raise ExampleError()
except ExampleError e:
throw e
except:
raise AnotherExampleError()
A quick test shows that the code will throw a TypeError if it reaches that line:
try:
raise BaseException
except not BaseException:
print("Test1")
except BaseException:
print("Test2")
Exception:
During handling of the above exception, another exception occurred:
Traceback (most recent call last): File "main.py", line 3, in
except not BaseException: TypeError: catching classes that do not inherit from BaseException is not allowed
I'm working on implementing a small programming languge in Python for the hell of it, and the language's execution basically consists of recursive calls to a function called execute. I've implemented my own error handling, but in order to have that error handling work I need to catch some exceptions and throw them as my own types, resulting in code that looks something like this:
def execute(...):
try:
try:
# do stuff
except IndexError:
raise MyIndexError()
except MyErrorBase as e:
raise MyErrorBase(e, newTracebackLevel) # add traceback level for this depth
I really hate the nested try blocks... is there any way to fix this?
If you really want to do this, try creating a mapping between base exception types and your new exception types:
exceptionMap = {
IndexError: MyIndexError,
# ...
}
def execute(...):
try:
# do stuff
except tuple(exceptionMap) as e:
raise exceptionMap[type(e)](e, newTracebackLevel)
Example:
In [33]: exceptionMap = {IndexError: RuntimeError}
In [34]: a = []
In [35]: try:
...: a[1]
...: except tuple(exceptionMap) as e:
...: raise exceptionMap[type(e)](str(e))
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
<ipython-input-35-bc6fdfc44fbe> in <module>()
2 a[1]
3 except tuple(exceptionMap) as e:
----> 4 raise exceptionMap[type(e)](str(e))
5
6
RuntimeError: list index out of range
You need to set try statements when ever needed.
Put it only on start of execution.
try statement is basically is a longjump. You want to do some long tasks which may fail at any place in the code it can be in inner calls. longjump helps you to catch fails.
In lua language there's method called pcall. (protected call)
Whenever it invokes at error the call returns error status and error message is taken as the second return value.
i wrote a code which is dumping numbers which is collected from serial port read as follows:
readoff = ser.readline()
and the proper format of readoff is follows:
a=' 213 -456 725'
and then for dumping and making some calculations im splitting it to 3 part and turning them to integer as follows:
splitted=readoff.split()
if len(splitted) == 3 :
temparrayforx.append(int(splitted[0]))
temparrayfory.append(int(splitted[1]))
temparrayforz.append(int(splitted[2]))
but sometimes from the serial port im reading something like: '2-264' which cannot turned into a integer. or sometimes readoff is not divisible to three.
here is my sample error:
temparrayforx.append(int(splitted[0]))
ValueError: invalid literal for int() with base 10: '2-264'
my goal is if the reading is not correct(if its not 3 part)(if its not a proper number), skip that readoff and go on(read another data). how can i do that ?
thanks for help
The standard python try-catch is:
try:
do_something_risky()
except ExceptionName as exc:
do_something_else()
It is very important to specify the exceptions you want to catch, otherwise you might catch unwanted exceptions that should bubble up, resulting in errors difficult to detect.
You can catch different exceptions and react in a different way to them:
try:
do_something_risky()
except SomeException as exc:
do_this()
except AnotherException as exc:
do_that()
Additionally you can add else and finally
try:
do_something_risky()
except ExceptionName, AnotherPossibleException as exc:
do_something_else()
else:
do_something_when_no_exception_raised()
finally:
# Useful for cleaning up
do_something_no_matter_what_happens()
In your case
try:
# Do the problematic thing
except ValueError as exc:
# Manage the exception
You should catch the specific exception that's being raised, ValueError in this case:
try:
temparrayforx.append(int(splitted[0]))
except ValueError as e:
print e
It's important to catch a specific error type so you don't accidentally catch lots of unexpected errors - like if splitted is empty, an IndexError would be raised. A bare 'except:' or 'except Exception:' would hide that from you.
In your case, since you want to catch a couple of different error cases (line doesn't have enough parts, value isn't a number) you can either catch both exception types in the same except clause or have two different except clauses - for example if you need to do different things with each problem.
I'm aware that it's possible to ignore exceptions in Python using try...except statements. Is it possible to ignore exceptions in Python when they occur, but still print them?
I tried ignoring the exception here, and therefore, the exception was not printed when it was encountered:
try:
num = 0
if num == 0:
raise Exception("Num must not be 0!")
except Exception:
pass
'''The exception is ignored, and is not printed.'''
I've written a simple source-to-source compiler that has a lot of exceptions like these, and I'm not sure how I can ignore the exceptions while still printing them. How can I ensure that the exceptions are printed to the console even when they are being ignored?
You can print an exception like this.
try:
x = 1 / 0
except Exception as e:
print e
EDIT:
As user1354557, gcbirzan, and Jonathan Vanasco pointed out, you can use the traceback and logging modules to get more precise error messages. Error messages printed out these ways will be more verbose, which is (usually) a good thing.
import traceback
try:
x = 1 / 0
except Exception as e:
print traceback.format_exc() # I prefer this to traceback.print_exc()
import logging
try:
x = 1 / 0
except Exception as e:
logging.exception(e)
If you want a printout of the stack trace, you can use the traceback module:
import traceback
try:
0/0
except:
traceback.print_exc()
This would print something like:
Traceback (most recent call last):
File "example.py", line 3, in <module>
0/0
ZeroDivisionError: integer division or modulo by zero
Is this what you're looking for?
You should take a look at the logging module. It has support for logging exceptions with traceback (either via logger.exception or by passing exc_info as a keyword parameter to any logging function).
By ignore, I suppose you mean you want to print it, but not catch it, and allow it to bubble up the call stack. You can do that by catching the exception, printing it, and then re-throwing it.
try :
# do something
except Exception as e:
print e
raise e
It's possible to do this globally, even in code you didn't write (such as a library module) using a trace function.
import sys
def print_exceptions(frame, event, arg):
if event == "exception":
sys.excepthook(*arg)
return print_exceptions
sys.settrace(print_exceptions)
Note that the trace function is called for every statement executed while it is in effect and may therefore significantly slow down your script's execution. Another minor issue is that any unhandled exception will be printed twice (once by this hook, again by Python itself when exiting the script).
If you want to customize the output, you can dig the information you want out of arg (it's a 3-tuple of the exception type, the error message, and a traceback object) and frame (which includes a reference to the current code object, from which its name can be obtained, as well as the source filename and line number).