My code its something like this:
if Number == 1:
except 1
except 2
If Number2 == 2:
except 1
except 2
How i can import a list of exceptions? without writing it everytime? something like:
ListExcept = ['ExceptError1', 'ExceptError2']
if Number == 1:
except ListExcept
Sorry for my bad example and english
A try clause can have any number of except clauses to handle different exceptions, however, only one will be executed in case an exception occurs.
We can use a tuple of values to specify multiple exceptions in an except clause.
You cannot use list!
TEST 1
try:
# do something
a = 10
b = 0
c = a/b
except (TypeError, ZeroDivisionError):
# handle multiple exceptions
# TypeError and ZeroDivisionError
pass
del a
del b
try:
# do something
b = 0
a = '10'
c = a/b
except (TypeError, ZeroDivisionError):
# handle multiple exceptions
# TypeError and ZeroDivisionError
pass
## No ERRORS
TEST 2
del a
del b
try:
# do something
a = 10
c = a/b
except (TypeError, ZeroDivisionError):
# handle multiple exceptions
# TypeError and ZeroDivisionError
pass
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-23-3726f056c576> in <module>()
30 # do something
31 a = 10
---> 32 c = a/b
33
34 except (TypeError, ZeroDivisionError):
NameError: name 'b' is not defined
TEST 3
FIXING
## fixing above error
try:
# do something
a = 10
c = a/b
except (TypeError, ZeroDivisionError, NameError):
# handle multiple exceptions
# TypeError and ZeroDivisionError and NameError
pass
Related
This question already has an answer here:
Why do I get a `NameError` (or `UnboundLocalError`) from using a named exception after the `except` block?
(1 answer)
Closed 1 year ago.
This code snippet works:
try:
raise Exception('oh no!')
except Exception as e:
error = e
print(error) # prints "oh no!"
This code snippet fails:
try:
raise Exception('oh no!')
except Exception as e:
e = e
print(e) # NameError: name 'e' is not defined
What's going on?
In Python,
except Exception as e:
error = e
is equivalent to
except Exception as e:
try:
error = e
finally:
del e
I.e., e is deleted after the except block. If you assign e to e, it will be deleted - however, this is only true for the alias. If you assign it to error, e will also be deleted but not error.
Source: https://docs.python.org/3/reference/compound_stmts.html#the-try-statement
I have come across a strange behavior using the python break statement within a try-except block.
i=0
lst=[]
while i < 5:
try:
if i < 3:
raise Exception('spam', 'eggs')
#lst[0]=i
print('-'+str(i)+'-')
break
except:
i=i+1
print(str(i)+' ',end='')
1 2 3 -3-
But if I remove the commented line:
i=0
lst=[]
while i < 5:
try:
if i < 3:
raise Exception('spam', 'eggs')
lst[0]=i
print('-'+str(i)+'-')
break
except:
i=i+1
print(str(i)+' ',end='')
1 2 3 4 5
Why has the list assignment caused the break to no longer happen? Can someone explain what is going on here.
lst is an empty list. Attempting to access elements that do not exist, such as lst[0] will raise an IndexError exception. That exception is then caught in the exception handler, corrupting your expected results.
First of all, you generally should not use bare exception handlers; restrict your exception handler to those exceptions that it knows how to handle. Unrestricted exception handlers make it possible for unexpected exceptions to be hidden, as is the case here.
If you want to store the index in lst either make sure that your list is long enough, or use append() or insert() to add it to the end or at the beginning of the list.
Using Exception to create your own exceptions is often not the best thing to do either because it makes it difficult to distinguish your exception from others:
for i in range(2):
try:
if i == 0:
raise Exception('spam', 'eggs')
else:
1/0 # cause ZeroDivisionError
except Exception as e:
print(repr(e))
Running that code outputs:
Exception('spam', 'eggs')
ZeroDivisionError('division by zero',)
Because ZeroDivisionError is a subclass of Exception it is also caught by the handler. To solve this you can create your own Exception subclass:
class MyException(Exception):
pass
Now you can easily check for the exception that you know how to handle:
for i in range(2):
try:
if i == 0:
raise MyException('spam', 'eggs')
else:
1/0 # cause ZeroDivisionError
except MyException as e:
print(repr(e))
Running this code:
MyException('spam', 'eggs')
Traceback (most recent call last):
File "", line 6, in
ZeroDivisionError: division by zero
shows that your custom exception is caught and handled, but unexpected exceptions are not. If you want to handle the unexpected ones too then add a second exception handler after the first:
except MyException as e:
print(repr(e))
except Exception as e:
print('Unexpected exception', e)
raise
If you treat the exception:
i=0
lst=[]
while i < 5:
try:
if i < 3:
raise Exception('spam', 'eggs')
lst[0]=i
print('-'+str(i)+'-')
break
except Exception as e:
print(e)
i=i+1
print(str(i))
You will realize that you get an IndexError:
list assignment index out of range
since your list is empty, you can not access/assign at that index. If you want to insert items to the list use append:
lst.append(i)
or insert:
lst.insert(0, i)
depending on what you want to do. Read more here.
In Python, I can assign alternative values to a variable if the first assignment to this variable raise exceptions, something like:
try:
a = 1/0
except Exception:
a = 0
I wonder can we replace the try/except with context manager?
Here what I tried:
from contextlib import contextmanager
#contextmanager
def tryo(*exception_list):
t = tuple(i for i in exception_list[0]
if isinstance(i,Exception) or (Exception,))
try:
yield
except t as e:
print e
with tryo([(Exception, 0)]):
a = 1/0
I guess I must do something instead of yield but don't know what must I do. Any suggestion?
The exception (ZeroDivisionError in this case) is not caused by assignment failure, but becasue of dividing by 0.
The first code can be converted as follow:
a = 0
try:
a = 1 / 0
except Exception: # ZeroDivisionError:
pass
How about the following approach (yielding default value, change the value in with statement body)?
>>> from contextlib import contextmanager
>>>
>>> #contextmanager
... def tryo(exceptions, default):
... try:
... yield default
... except exceptions:
... pass
...
>>> with tryo((Exception), 0) as a: # ZeroDivisionError:
... a = 1 / 0
...
>>> with tryo((Exception), 0) as b: # ZeroDivisionError:
... b = 4 / 2
...
>>> a
0
>>> b
2.0
There is no way for the context manager to know what you are doing within the context. It especially won’t be able to tell which variable you are assigning a value to; it also won’t be able to access that variable; and even if it could, there would be no guarantee that you only did that one assigment inside the context manager too. So, no, you can’t do it like that.
What you could do however, is to do it the other way around. Your 0 is a default value, so you would set that one first. Afterwards, you try to assign your actual value 1/0 and ignore the ZeroDivisionError. So it would look like this:
a = 0
try:
a = 1/0
except ZeroDivisionError:
pass
And that you can do with a context manager, with contextlib.suppress:
a = 0
with suppress(ZeroDivisionError):
a = 1/0
you can use Decorator like:
def my_decorator(exception_list):
def real_decorator(func):
def fn_wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except tuple(e for e, _ in exception_list) as e:
for error, default in exception_list:
if isinstance(e, error):
return default
else:
# this Exception not in exception_list
raise e
return fn_wrapper
return real_decorator
#my_decorator([(ZeroDivisionError, 1),
(IndexError, 2),
(ValueError, 3),
(Exception, 0)],
)
def div_working():
import random
e = random.choice((ZeroDivisionError, IndexError, ValueError, Exception, 100, 200, 300))
if isinstance(e, int):
return e
else:
print e
raise e
for _ in range(10):
a = div_working()
print a
print "= " * 10
Is it correct to call that function in some exceptions ?
Is that process correct ? Is it better to process each exceptions ?
def close_all():
try:
ftp.close()
except:
pass
try:
tar.close()
except:
pass
try:
savelist.close()
except:
pass
try:
os.remove(tarname)
except:
pass
exit()
Thanks in advance.
I think you should handle each exception one by one. This will shorten your code. First of all note all the exceptions that ftp.close() and other methods will raise. Then handle them one by one.
Example:
>>> a = 5 # a is an integer
>>> b = "Bingo" # b is a string
>>>
>>> def add_five():
try:
c + 5 # c is not defined. NameError exception is raised
except NameError:
b + 5 # b is a string. TypeError exception is raised
except TypeError:
a + 5 # a is int. No exception is raised
except:
# This last except clause is just in case you forgot to handle any exception
pass
>>>
I'm really new in Python and a have no experience with exceptions but I've read all the documentation and couldn't find an answer ... so I'm looking for a deeper view in except's semantics.
When we have for example:
try:
x = 2
except GreaterThanOne:
print("The value is greater than one")
In this case I want the message to be printed.Is there a way for the GreaterThanOne class(exception) to be defined to raise when the entered value is greater than one ?
Ok, let me be more specific ...
Every error raises by a specific rule which should be add in the error attributes, am I right ?
For example:
try:
myvalue = x / y
except ZeroDivisionError:
print("Some error message printed ...")
So when I use this code and enter for y to be 0 the exception ZeroDivisionError will raise ... Can I for example redefine ZeroDivisionError to raise like this but if y is set to be ... 2 or 3 or any other value ?
Input:
x = 10
y = 2
try:
myvalue = x / y
except ZeroDivisionError:
print("division by 2")
Output: division by 2
Here's an example that should help you understand. Run this in your Python interpreter and watch how the exception is raised and caught (or not caught) when you call set_val(2).
# Defining our Exception subclass:
class GreaterThanOne(Exception):
pass
# The global value we pretend to care about:
val = 0
# Function to set a value but possibly raise our new Exception
def set_val(new_val):
if new_val > 1:
raise GreaterThanOne("%d > 1" % new_val)
val = new_val
# Catching exception:
try:
set_val(0)
set_val(1)
set_val(2)
except GreaterThanOne:
print "Whoops - one of those values was greater than one"
# Not catching exception:
set_val(0)
set_val(1)
set_val(2)
set_val(3)
an try-except block catches exception in this block.
try:
#some stuff here
except ExceptionClass as e:
#Exception handling here
the class after the except keyword indicates which kind of exception you want to catch. Usually you give a specific class, like ValueError or KeyError. You can also use the Exception class, to catch any exception. Because all the other exceptionclasses inhert from Exception.
so if you want to use this construct, an exception needs to be raised, Either by a function / method you call, or you raise it yourself with the raise keyword.
like this:
try:
raise KeyError('Just for test')
except KeyError as e:
#Exception handling here
The try except doesn't automagically inspect the whole code between it, it just looks for exceptions... Or to be more specific, it looks for those exceptions you tell it to look for.
Of course you can also inspect the exception instance.
try:
raise KeyError('Just for test')
except KeyError as e:
print e.args
For more information, please see:
http://docs.python.org/2/tutorial/errors.html