How do I catch multiple exceptions in one line (except block)
Do this:
try:
may_raise_specific_errors():
except (SpecificErrorOne, SpecificErrorTwo) as error:
handle(error) # might log or have some other default behavior...
The parentheses are required due to older syntax that used the commas to assign the error object to a name. The as
keyword is used for the assignment. You can use any name for the error object, I prefer error
personally.
Best Practice
To do this in a manner currently and forward compatible with Python, you need to separate the Exceptions with commas and wrap them with parentheses to differentiate from earlier syntax that assigned the exception instance to a variable name by following the Exception type to be caught with a comma.
Here’s an example of simple usage:
import sys
try:
mainstuff()
except (KeyboardInterrupt, EOFError): # the parens are necessary
sys.exit(0)
I’m specifying only these exceptions to avoid hiding bugs, which if I encounter I expect the full stack trace from.
This is documented here: https://docs.python.org/tutorial/errors.html
You can assign the exception to a variable, (e
is common, but you might prefer a more verbose variable if you have long exception handling or your IDE only highlights selections larger than that, as mine does.) The instance has an args attribute. Here is an example:
import sys
try:
mainstuff()
except (KeyboardInterrupt, EOFError) as err:
print(err)
print(err.args)
sys.exit(0)
Note that in Python 3, the err
object falls out of scope when the except
block is concluded.
Deprecated
You may see code that assigns the error with a comma. This usage, the only form available in Python 2.5 and earlier, is deprecated, and if you wish your code to be forward compatible in Python 3, you should update the syntax to use the new form:
import sys
try:
mainstuff()
except (KeyboardInterrupt, EOFError), err: # don't do this in Python 2.6+
print err
print err.args
sys.exit(0)
If you see the comma name assignment in your codebase, and you’re using Python 2.5 or higher, switch to the new way of doing it so your code remains compatible when you upgrade.
The suppress
context manager
The accepted answer is really 4 lines of code, minimum:
try:
do_something()
except (IDontLikeYouException, YouAreBeingMeanException) as e:
pass
The try
, except
, pass
lines can be handled in a single line with the suppress context manager, available in Python 3.4:
from contextlib import suppress
with suppress(IDontLikeYouException, YouAreBeingMeanException):
do_something()
So when you want to pass
on certain exceptions, use suppress
.
When a program encounters an exception during execution, it is terminated if the exception is not handled. By handling multiple exceptions, a program can respond to different exceptions without terminating it.
In Python, try-except
blocks can be used to catch and respond to one or multiple exceptions. In cases where a process raises more than one possible exception, they can all be handled using a single except
clause.
There are several approaches for handling multiple exceptions in Python, the most common of which are discussed below.
Install the Python SDK to identify and fix exceptions
Using Same Code Block for Multiple Exceptions
With this approach, the same code block is executed if any of the listed exceptions occurs. Here’s an example:
try:
name = 'Bob'
name += 5
except (NameError, TypeError) as error:
print(error)
rollbar.report_exc_info()
In the above example, the code in the except
block will be executed if any of the listed exceptions occurs. Running the above code raises a TypeError
, which is handled by the code, producing the following output:
cannot concatenate 'str' and 'int' objects
Using Different Code Blocks for Multiple Exceptions
If some exceptions need to be handled differently, they can be placed in their own except
clause:
try:
name = 'Bob'
name += 5
except NameError as ne:
# Code to handle NameError
print(ne)
rollbar.report_exc_info()
except TypeError as te:
# Code to handle TypeError
print(te)
rollbar.report_exc_info()
In the above example, NameError
and TypeError
are two possible exceptions in the code, which are handled differently in their own except blocks.
Investigating Exceptions using If, Elif, Else Statements
Exceptions can also be checked using if-elif-else
conditions, which can be useful if the exception needs to be investigated further:
import errno
try:
f = open('/opt/tmp/myfile.txt')
except IOError as e:
rollbar.report_exc_info()
if e.errno == errno.ENOENT:
print('File not found')
elif e.errno == errno.EACCES:
print('Permission denied')
else:
print e
Here, the variable e
holds an instance of the raised IOError
. The additional status code of the exception is checked in the if
, elif
and else
blocks and the first match is executed:
File not found
Multiple Except Clauses Matching
There may be cases where a piece of code causes an exception that can match multiple except
clauses:
try:
f = open('/opt/tmp/myfile.txt')
except EnvironmentError:
rollbar.report_exc_info()
print('Failed to open file')
except IOError:
rollbar.report_exc_info()
print('File not found')
Since EnvironmentError
is more general than IOError
, it matches the exception in the code above. The EnvironmentError except
clause is listed first, so the code within it gets executed, producing the following output:
Failed to open file
Track, Analyze and Manage Errors With Rollbar
Managing errors and exceptions in your code is challenging. It can make deploying production code an unnerving experience. Being able to track, analyze, and manage errors in real-time can help you to proceed with more confidence. Rollbar automates error monitoring and triaging, making fixing Python errors easier than ever. Sign Up Today!
In this Python tutorial, we will learn Python catch multiple exceptions and also we will cover these topics:
- Python catching exceptions
- Python catch different exception types
- Python catch multiple exceptions in one line
- Python catch-all exceptions
- Python handle different exception types
- Catch multiple exceptions python3
- User-defined exceptions in python
- Customized Excepting classes
Now, we can see catch multiple exceptions in python.
- In this example, I have imported a module called math and declared a variable as integers, and assigned it as integers =[‘orange’,6,-8’apple’].
- The for loop is used for iteration and try is used. The try statement allows defining a block of code that tests the error while it is being executed.
- If any error occurs try will be skipped and except will execute. Here the error was ‘orange’ so the except executed as “The input is not supported“.
- Another input is -8 which was a negative number again except is executed as a number is not a positive integer and the error message is displayed.
Example:
import math
integers = ['orange',6,-8,'apple']
for number in integers:
try:
number_factorial = math.factorial(number)
except TypeError:
print("The input is not supported.")
except ValueError:
print( number," is not a positive integer.")
In the below screenshot, we can see the error message as the output:
You may also like Python Exceptions Handling and Python concatenate list with examples.
Python catching exceptions
Now, we can see catching exceptions in python.
- In this example, I have imported a module called sys and random and declared a variable as numberlist and assigned numberlist = [‘a’, 2, 2].
- The for loop is used for iteration and try block is used as the first number from the list is not an integer an error occurred.
- So except is executed as next entry and also it gives ValueError.
- The second number is taken and the addition operation performed and the result is displayed.
- The sys.exc_info is used to obtain exception information like formats of results and prints the text.
Example:
import sys
import random
numberlist = ['a', 2, 2]
for number in numberlist:
try:
print("The 1st number is", number)
r = 1+int(number)
break
except:
print("k", sys.exc_info()[0], "value.")
print("Next entry.")
print("The addition of", number, "is", r)
Below screenshot shows the output:
Python catch different exception types
Now, we can see how to catch different exception types in python.
- In this example, I have imported a module called sys, and try block is used to identify the error.
- The division operation is performed, as the zero can’t be divided by any number ZeroDivisionError occur except is executed and “The zero can’t be divided” is displayed.
- The addition operation is performed as the input is given in the string format so the error is generated and as the exception is given as TypeError.
- So the except is executed and displayed as ‘The number is in the string format‘.
Example:
import sys
try:
n = 0
m = 2
c = m/n
except(ZeroDivisionError) as e:
print("The zero can't be divided")
try:
n = 2
m = '3'
p = m+n
except TypeError:
print('The number is in the string format')
You can refer to the below screenshot for the output:
Python catch multiple exceptions in one line
Now, we can see how to catch multi exception in one line in python.
- In this example, I have imported a module called sys, try block is used and declared a variable as a number.
- Here, number = number+’5′ and assigned multiple exceptions in one line in the except and except is executed.
Example:
import sys
try:
number = 2
number = number+'5'
except(TypeError, SyntaxError, ValueError)as e:
print("The number is given in string format")
You refer to the below screenshot for the output:
Python catch-all exceptions
Now, we can see how to catch all exceptions in python.
- In this example, I have taken all exceptions by taking different except for different examples.
- I have used try block to check the errors and used excepts if the error is present excepts are executed.
Example:
try:
print(python)
except NameError:
print("python is not defined")
try:
list = [1,2,3]
print(list[5])
except IndexError as e:
print(e)
print("index error")
try:
from cv import numpy
except Exception:
print("improper module")
try:
print(hello)
except:
print("hello is not defined")
finally:
print(" The finally is executed")
try:
print(chair)
except NameError:
print ("NameError:'cot' is not defined")
else:
print ("word found no error")
The below screenshot shows the output.
Python handle different exception types
Now, we can see how to handle different exception types in python.
- In this example, I have taken three different exception types as except ZeroDivisionError, except TypeError, and except Exception.
- I have used try block to check the errors and used excepts if the error is present excepts are executed.
Example:
try:
n = 0
m = 3
c = m/n
except(ZeroDivisionError) as e:
print("The zero can't be divided")
try:
n = 2
m = 'HEllo'
p = m+n
except TypeError:
print('The number is in the string format')
try:
from cv import pandas
except Exception:
print("improper module")
Below screenshot shows the output with examples that is having different excepts in it.
Catch multiple exceptions python3
Now, we can see how to Catch multiple exceptions python3.
- In this example, I have used multiple exceptions like except TypeError, except, except SyntaxError as e.
- All these multiple exceptions are used with different examples.
- I have used try block to check the errors and used excepts if the error is present excepts are executed.
Example:
try:
print(x)
except TypeError:
print("x is not defined")
except:
print("Error")
try:
print(a+b)
except:
print("exception occured")
try:
print(hello)
except SyntaxError as e:
print("Invalid syntax")
except:
print("Invalid syntax")
Below screenshot shows the output:
User-defined exceptions in python
Here, we can see User-defined exceptions in python.
- In this example, I have defined the class as class Number(Exception) and another two classes are to define exceptions to create two errors such as class SmallNumberError(Number).
- Another error is class LargeNumberError(Number), while a condition is true I have used try block, and if condition is not satisfied except is executed.
Example:
class Number(Exception):
pass
class SmallNumberError(Number):
pass
class LargeNumberError(Number):
pass
number = 5
while True:
try:
Input = int(input("Enter a number: "))
if Input < number:
raise SmallNumberError
elif Input > number:
raise LargeNumberError
break
except SmallNumberError:
print("The number is small")
print()
except LargeNumberError:
print("The number is large")
When condition is not true the userdefined exception is executed. You can refer to the below screenshot for the output:
Customized Excepting classes
Now, we can see how to customized Excepting Classes in python.
- In this example, We have overridden the constructor of the Exception class to pass the arguments such as self, cash, message.
- Then constructor of the parent exception class is called by using self.message by using super(). The attribute self.cash is defined.
- To get the error message, I have written Cash is not in (2000, 1000) range.
Example:
class CashNotInRangeError(Exception):
def __init__(self, cash, message="Cash is not in (2000, 1000) range"):
self.cash = cash
self.message = message
super().__init__(self.message)
cash = int(input("Enter cash: "))
if not 2000 < cash < 1000:
raise CashNotInRangeError(cash)
The below screenshot shows the ouput:
You may like the following python tutorials:
- What is a Python Dictionary + Create a dictionary in Python
- Python print without newline
- Python Dictionary Methods
- How to create a list in Python
- How to convert an integer to string in python
- How to concatenate strings in python
- How to split a string using regex in python
- Python intersection of sets
In this tutorial, we have learned about Python catch multiple exceptions, and also we have covered these topics:
- Python catching exceptions
- Python catch different exception types
- Python catch multiple exceptions in one line
- Python catch-all exceptions
- Python handle different exception types
- Catch multiple exceptions python3
- User-defined exceptions in python
- Customized Excepting classes
Python is one of the most popular languages in the United States of America. I have been working with Python for a long time and I have expertise in working with various libraries on Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… I have experience in working with various clients in countries like United States, Canada, United Kingdom, Australia, New Zealand, etc. Check out my profile.
In the previous blog, we learned about python decorators and generators. This time we are going to learn about Error Handling in Python. In this blog, we will learn about both the simple exception and Multiple Exception Handling in Python using Try, Except, and Finally Statement.
Why should we Handle the error?
The Answer is we handle the errors for the proper functioning of our program. Think you made a web server using python and didn’t handle the errors.
When the server goes to production any kind of error can occur and the webserver will stop.
To make sure that the webserver keeps running you will have to handle the errors.
Python Exception – Try and Except
There are many built-in Exceptions in Python. Let’s Learn some of the basic ones with the help of examples:
Zero Division Error
>>> 10 / 0
Traceback (most recent call last):
File ".main.py", line 1, in
10 / 0
ZeroDivisionError: division by zero
This is ZeroDivisionError
, returned when we try to divide anything with zero.
Index Error
>>> lst = [1, 2, 3, 4]
>>> print(lst[5])
Traceback (most recent call last):
File ".main.py", line 2, in
print(lst[5])
IndexError: list index out of range
This error is returned when we try to access the index, not present in the array.
Let’s Now try to Handle Both the Errors:
try:
a = 10/0
except ZeroDivisionError as e:
print("Can't Divide by Zero -", e)
Can't Divide by Zero - division by zero
Handle the IndexError:
try:
lst = [1, 2, 3, 4]
print(lst[5])
except IndexError as e:
print("Index out of Bound -", e)
Index out of Bound - list index out of range
Now let’s understand how the try and except block works in python.
First, the code inside the try block is run. If no error occurs, an exception is raised and the code inside the except block is executed, else the except block is skipped.
Learn Python List Comprehension and Inner Function.
Python Exception Error Type
Everything is an object in Python. The errors are also a class.
Example:
>>> print(IndexError.__class__)
>>> print(ZeroDivisionError.__class__)
<class 'type'>
<class 'type'>
Catch all Exceptions
We can also catch all exceptions in a single except block.
Example:
try:
lst = [1, 2, 3, 4]
a = 10 / 0
print(lst[5])
except Exception:
print("An Error Occured")
An Error Occured
Handle Multiple Exceptions in Python
Python also supports multiple exception handling.
A single except block can be used to catch many exceptions.
Example:
try:
lst = [1, 2, 3, 4]
a = 10 / 0
print(lst[5])
except (ZeroDivisionError, IndexError) as e:
print("An Error Occured -", e)
An Error Occured - division by zero
try:
lst = [1, 2, 3, 4]
print(lst[5])
a = 10 / 0
except (ZeroDivisionError, IndexError) as e:
print("An Error Occured -", e)
An Error Occured - list index out of range
Python Error Handling Finally Statement
Finally, the statement is always executed every time and after try and the except block.
try:
lst = [1, 2, 3, 4]
print(lst[5])
a = 10 / 0
except (ZeroDivisionError, IndexError) as e:
print(e)
finally:
print("Error Handled")
list index out of range
Error Handled
Hope you like it!
Improve Article
Save Article
Improve Article
Save Article
Given a piece of code that can throw any of several different exceptions, and one needs to account for all of the potential exceptions that could be raised without creating duplicate code or long, meandering code passages.
If you can handle different exceptions all using a single block of code, they can be grouped together in a tuple as shown in the code given below :
Code #1 :
try
:
client_obj.get_url(url)
except
(URLError, ValueError, SocketTimeout):
client_obj.remove_url(url)
The remove_url()
method will be called if any of the listed exceptions occurs. If, on the other hand, if one of the exceptions has to be handled differently, then put it into its own except clause as shown in the code given below :
Code #2 :
try
:
client_obj.get_url(url)
except
(URLError, ValueError):
client_obj.remove_url(url)
except
SocketTimeout:
client_obj.handle_url_timeout(url)
Many exceptions are grouped into an inheritance hierarchy. For such exceptions, all of the exceptions can be caught by simply specifying a base class. For example, instead of writing code as shown in the code given below –
Code #3 :
try
:
f
=
open
(filename)
except
(FileNotFoundError, PermissionError):
...
Except statement can be re-written as in the code given below. This works because OSError
is a base class that’s common to both the FileNotFoundError
and PermissionError exceptions.
Code #4 :
try
:
f
=
open
(filename)
except
OSError:
...
Although it’s not specific to handle multiple exceptions per se, it is worth noting that one can get a handle to the thrown exception using them as a keyword as shown in the code given below.
Code #5 :
try
:
f
=
open
(filename)
except
OSError as e:
if
e.errno
=
=
errno.ENOENT:
logger.error(
'File not found'
)
elif
e.errno
=
=
errno.EACCES:
logger.error(
'Permission denied'
)
else
:
logger.error(
'Unexpected error: % d'
, e.errno)
The e variable holds an instance of the raised OSError. This is useful if the exception has to be invested further, such as processing it based on the value of the additional status code. The except clauses are checked in the order listed and the first match executes.
Code #6 : Create situations where multiple except clauses might match
Output :
Traceback (most recent call last): File "", line 1, in FileNotFoundError: [Errno 2] No such file or directory: 'miss
try
:
f
=
open
(
'missing'
)
except
OSError:
print
(
'It failed'
)
except
FileNotFoundError:
print
(
'File not found'
)
Output :
Failed
Here the except FileNotFoundError
clause doesn’t execute because the OSError
is more general, matches the FileNotFoundError exception, and was listed first.
Содержание:развернуть
- Как устроен механизм исключений
- Как обрабатывать исключения в Python (try except)
-
As — сохраняет ошибку в переменную
-
Finally — выполняется всегда
-
Else — выполняется когда исключение не было вызвано
-
Несколько блоков except
-
Несколько типов исключений в одном блоке except
-
Raise — самостоятельный вызов исключений
-
Как пропустить ошибку
- Исключения в lambda функциях
- 20 типов встроенных исключений в Python
- Как создать свой тип Exception
Программа, написанная на языке Python, останавливается сразу как обнаружит ошибку. Ошибки могут быть (как минимум) двух типов:
- Синтаксические ошибки — возникают, когда написанное выражение не соответствует правилам языка (например, написана лишняя скобка);
- Исключения — возникают во время выполнения программы (например, при делении на ноль).
Синтаксические ошибки исправить просто (если вы используете IDE, он их подсветит). А вот с исключениями всё немного сложнее — не всегда при написании программы можно сказать возникнет или нет в данном месте исключение. Чтобы приложение продолжило работу при возникновении проблем, такие ошибки нужно перехватывать и обрабатывать с помощью блока try/except
.
Как устроен механизм исключений
В Python есть встроенные исключения, которые появляются после того как приложение находит ошибку. В этом случае текущий процесс временно приостанавливается и передает ошибку на уровень вверх до тех пор, пока она не будет обработано. Если ошибка не будет обработана, программа прекратит свою работу (а в консоли мы увидим Traceback с подробным описанием ошибки).
💁♂️ Пример: напишем скрипт, в котором функция ожидает число, а мы передаём сроку (это вызовет исключение «TypeError»):
def b(value):
print("-> b")
print(value + 1) # ошибка тут
def a(value):
print("-> a")
b(value)
a("10")
> -> a
> -> b
> Traceback (most recent call last):
> File "test.py", line 11, in <module>
> a("10")
> File "test.py", line 8, in a
> b(value)
> File "test.py", line 3, in b
> print(value + 1)
> TypeError: can only concatenate str (not "int") to str
В данном примере мы запускаем файл «test.py» (через консоль). Вызывается функция «a«, внутри которой вызывается функция «b«. Все работает хорошо до сточки print(value + 1)
. Тут интерпретатор понимает, что нельзя конкатенировать строку с числом, останавливает выполнение программы и вызывает исключение «TypeError».
Далее ошибка передается по цепочке в обратном направлении: «b» → «a» → «test.py«. Так как в данном примере мы не позаботились обработать эту ошибку, вся информация по ошибке отобразится в консоли в виде Traceback.
Traceback (трассировка) — это отчёт, содержащий вызовы функций, выполненные в определенный момент. Трассировка помогает узнать, что пошло не так и в каком месте это произошло.
Traceback лучше читать снизу вверх ↑
В нашем примере Traceback
содержится следующую информацию (читаем снизу вверх):
TypeError
— тип ошибки (означает, что операция не может быть выполнена с переменной этого типа);can only concatenate str (not "int") to str
— подробное описание ошибки (конкатенировать можно только строку со строкой);- Стек вызова функций (1-я линия — место, 2-я линия — код). В нашем примере видно, что в файле «test.py» на 11-й линии был вызов функции «a» со строковым аргументом «10». Далее был вызов функции «b».
print(value + 1)
это последнее, что было выполнено — тут и произошла ошибка. most recent call last
— означает, что самый последний вызов будет отображаться последним в стеке (в нашем примере последним выполнилсяprint(value + 1)
).
В Python ошибку можно перехватить, обработать, и продолжить выполнение программы — для этого используется конструкция try ... except ...
.
Как обрабатывать исключения в Python (try except)
В Python исключения обрабатываются с помощью блоков try/except
. Для этого операция, которая может вызвать исключение, помещается внутрь блока try
. А код, который должен быть выполнен при возникновении ошибки, находится внутри except
.
Например, вот как можно обработать ошибку деления на ноль:
try:
a = 7 / 0
except:
print('Ошибка! Деление на 0')
Здесь в блоке try
находится код a = 7 / 0
— при попытке его выполнить возникнет исключение и выполнится код в блоке except
(то есть будет выведено сообщение «Ошибка! Деление на 0»). После этого программа продолжит свое выполнение.
💭 PEP 8 рекомендует, по возможности, указывать конкретный тип исключения после ключевого слова except
(чтобы перехватывать и обрабатывать конкретные исключения):
try:
a = 7 / 0
except ZeroDivisionError:
print('Ошибка! Деление на 0')
Однако если вы хотите перехватывать все исключения, которые сигнализируют об ошибках программы, используйте тип исключения Exception
:
try:
a = 7 / 0
except Exception:
print('Любая ошибка!')
As — сохраняет ошибку в переменную
Перехваченная ошибка представляет собой объект класса, унаследованного от «BaseException». С помощью ключевого слова as
можно записать этот объект в переменную, чтобы обратиться к нему внутри блока except
:
try:
file = open('ok123.txt', 'r')
except FileNotFoundError as e:
print(e)
> [Errno 2] No such file or directory: 'ok123.txt'
В примере выше мы обращаемся к объекту класса «FileNotFoundError» (при выводе на экран через print
отобразится строка с полным описанием ошибки).
У каждого объекта есть поля, к которым можно обращаться (например если нужно логировать ошибку в собственном формате):
import datetime
now = datetime.datetime.now().strftime("%d-%m-%Y %H:%M:%S")
try:
file = open('ok123.txt', 'r')
except FileNotFoundError as e:
print(f"{now} [FileNotFoundError]: {e.strerror}, filename: {e.filename}")
> 20-11-2021 18:42:01 [FileNotFoundError]: No such file or directory, filename: ok123.txt
Finally — выполняется всегда
При обработке исключений можно после блока try
использовать блок finally
. Он похож на блок except
, но команды, написанные внутри него, выполняются обязательно. Если в блоке try
не возникнет исключения, то блок finally
выполнится так же, как и при наличии ошибки, и программа возобновит свою работу.
Обычно try/except
используется для перехвата исключений и восстановления нормальной работы приложения, а try/finally
для того, чтобы гарантировать выполнение определенных действий (например, для закрытия внешних ресурсов, таких как ранее открытые файлы).
В следующем примере откроем файл и обратимся к несуществующей строке:
file = open('ok.txt', 'r')
try:
lines = file.readlines()
print(lines[5])
finally:
file.close()
if file.closed:
print("файл закрыт!")
> файл закрыт!
> Traceback (most recent call last):
> File "test.py", line 5, in <module>
> print(lines[5])
> IndexError: list index out of range
Даже после исключения «IndexError», сработал код в секции finally
, который закрыл файл.
p.s. данный пример создан для демонстрации, в реальном проекте для работы с файлами лучше использовать менеджер контекста with.
Также можно использовать одновременно три блока try/except/finally
. В этом случае:
- в
try
— код, который может вызвать исключения; - в
except
— код, который должен выполниться при возникновении исключения; - в
finally
— код, который должен выполниться в любом случае.
def sum(a, b):
res = 0
try:
res = a + b
except TypeError:
res = int(a) + int(b)
finally:
print(f"a = {a}, b = {b}, res = {res}")
sum(1, "2")
> a = 1, b = 2, res = 3
Else — выполняется когда исключение не было вызвано
Иногда нужно выполнить определенные действия, когда код внутри блока try
не вызвал исключения. Для этого используется блок else
.
Допустим нужно вывести результат деления двух чисел и обработать исключения в случае попытки деления на ноль:
b = int(input('b = '))
c = int(input('c = '))
try:
a = b / c
except ZeroDivisionError:
print('Ошибка! Деление на 0')
else:
print(f"a = {a}")
> b = 10
> c = 1
> a = 10.0
В этом случае, если пользователь присвоит переменной «с» ноль, то появится исключение и будет выведено сообщение «‘Ошибка! Деление на 0′», а код внутри блока else
выполняться не будет. Если ошибки не будет, то на экране появятся результаты деления.
Несколько блоков except
В программе может возникнуть несколько исключений, например:
- Ошибка преобразования введенных значений к типу
float
(«ValueError»); - Деление на ноль («ZeroDivisionError»).
В Python, чтобы по-разному обрабатывать разные типы ошибок, создают несколько блоков except
:
try:
b = float(input('b = '))
c = float(input('c = '))
a = b / c
except ZeroDivisionError:
print('Ошибка! Деление на 0')
except ValueError:
print('Число введено неверно')
else:
print(f"a = {a}")
> b = 10
> c = 0
> Ошибка! Деление на 0
> b = 10
> c = питон
> Число введено неверно
Теперь для разных типов ошибок есть свой обработчик.
Несколько типов исключений в одном блоке except
Можно также обрабатывать в одном блоке except сразу несколько исключений. Для этого они записываются в круглых скобках, через запятую сразу после ключевого слова except
. Чтобы обработать сообщения «ZeroDivisionError» и «ValueError» в одном блоке записываем их следующим образом:
try:
b = float(input('b = '))
c = float(input('c = '))
a = b / c
except (ZeroDivisionError, ValueError) as er:
print(er)
else:
print('a = ', a)
При этом переменной er
присваивается объект того исключения, которое было вызвано. В результате на экран выводятся сведения о конкретной ошибке.
Raise — самостоятельный вызов исключений
Исключения можно генерировать самостоятельно — для этого нужно запустить оператор raise
.
min = 100
if min > 10:
raise Exception('min must be less than 10')
> Traceback (most recent call last):
> File "test.py", line 3, in <module>
> raise Exception('min value must be less than 10')
> Exception: min must be less than 10
Перехватываются такие сообщения точно так же, как и остальные:
min = 100
try:
if min > 10:
raise Exception('min must be less than 10')
except Exception:
print('Моя ошибка')
> Моя ошибка
Кроме того, ошибку можно обработать в блоке except
и пробросить дальше (вверх по стеку) с помощью raise
:
min = 100
try:
if min > 10:
raise Exception('min must be less than 10')
except Exception:
print('Моя ошибка')
raise
> Моя ошибка
> Traceback (most recent call last):
> File "test.py", line 5, in <module>
> raise Exception('min must be less than 10')
> Exception: min must be less than 10
Как пропустить ошибку
Иногда ошибку обрабатывать не нужно. В этом случае ее можно пропустить с помощью pass
:
try:
a = 7 / 0
except ZeroDivisionError:
pass
Исключения в lambda функциях
Обрабатывать исключения внутри lambda функций нельзя (так как lambda записывается в виде одного выражения). В этом случае нужно использовать именованную функцию.
20 типов встроенных исключений в Python
Иерархия классов для встроенных исключений в Python выглядит так:
BaseException
SystemExit
KeyboardInterrupt
GeneratorExit
Exception
ArithmeticError
AssertionError
...
...
...
ValueError
Warning
Все исключения в Python наследуются от базового BaseException
:
SystemExit
— системное исключение, вызываемое функциейsys.exit()
во время выхода из приложения;KeyboardInterrupt
— возникает при завершении программы пользователем (чаще всего при нажатии клавиш Ctrl+C);GeneratorExit
— вызывается методомclose
объектаgenerator
;Exception
— исключения, которые можно и нужно обрабатывать (предыдущие были системными и их трогать не рекомендуется).
От Exception
наследуются:
1 StopIteration
— вызывается функцией next в том случае если в итераторе закончились элементы;
2 ArithmeticError
— ошибки, возникающие при вычислении, бывают следующие типы:
FloatingPointError
— ошибки при выполнении вычислений с плавающей точкой (встречаются редко);OverflowError
— результат вычислений большой для текущего представления (не появляется при операциях с целыми числами, но может появиться в некоторых других случаях);ZeroDivisionError
— возникает при попытке деления на ноль.
3 AssertionError
— выражение, используемое в функции assert
неверно;
4 AttributeError
— у объекта отсутствует нужный атрибут;
5 BufferError
— операция, для выполнения которой требуется буфер, не выполнена;
6 EOFError
— ошибка чтения из файла;
7 ImportError
— ошибка импортирования модуля;
8 LookupError
— неверный индекс, делится на два типа:
IndexError
— индекс выходит за пределы диапазона элементов;KeyError
— индекс отсутствует (для словарей, множеств и подобных объектов);
9 MemoryError
— память переполнена;
10 NameError
— отсутствует переменная с данным именем;
11 OSError
— исключения, генерируемые операционной системой:
ChildProcessError
— ошибки, связанные с выполнением дочернего процесса;ConnectionError
— исключения связанные с подключениями (BrokenPipeError, ConnectionResetError, ConnectionRefusedError, ConnectionAbortedError);FileExistsError
— возникает при попытке создания уже существующего файла или директории;FileNotFoundError
— генерируется при попытке обращения к несуществующему файлу;InterruptedError
— возникает в том случае если системный вызов был прерван внешним сигналом;IsADirectoryError
— программа обращается к файлу, а это директория;NotADirectoryError
— приложение обращается к директории, а это файл;PermissionError
— прав доступа недостаточно для выполнения операции;ProcessLookupError
— процесс, к которому обращается приложение не запущен или отсутствует;TimeoutError
— время ожидания истекло;
12 ReferenceError
— попытка доступа к объекту с помощью слабой ссылки, когда объект не существует;
13 RuntimeError
— генерируется в случае, когда исключение не может быть классифицировано или не подпадает под любую другую категорию;
14 NotImplementedError
— абстрактные методы класса нуждаются в переопределении;
15 SyntaxError
— ошибка синтаксиса;
16 SystemError
— сигнализирует о внутренне ошибке;
17 TypeError
— операция не может быть выполнена с переменной этого типа;
18 ValueError
— возникает когда в функцию передается объект правильного типа, но имеющий некорректное значение;
19 UnicodeError
— исключение связанное с кодирование текста в unicode
, бывает трех видов:
UnicodeEncodeError
— ошибка кодирования;UnicodeDecodeError
— ошибка декодирования;UnicodeTranslateError
— ошибка переводаunicode
.
20 Warning
— предупреждение, некритическая ошибка.
💭 Посмотреть всю цепочку наследования конкретного типа исключения можно с помощью модуля inspect
:
import inspect
print(inspect.getmro(TimeoutError))
> (<class 'TimeoutError'>, <class 'OSError'>, <class 'Exception'>, <class 'BaseException'>, <class 'object'>)
📄 Подробное описание всех классов встроенных исключений в Python смотрите в официальной документации.
Как создать свой тип Exception
В Python можно создавать свои исключения. При этом есть одно обязательное условие: они должны быть потомками класса Exception
:
class MyError(Exception):
def __init__(self, text):
self.txt = text
try:
raise MyError('Моя ошибка')
except MyError as er:
print(er)
> Моя ошибка
С помощью try/except
контролируются и обрабатываются ошибки в приложении. Это особенно актуально для критически важных частей программы, где любые «падения» недопустимы (или могут привести к негативным последствиям). Например, если программа работает как «демон», падение приведет к полной остановке её работы. Или, например, при временном сбое соединения с базой данных, программа также прервёт своё выполнение (хотя можно было отловить ошибку и попробовать соединиться в БД заново).
Вместе с try/except
можно использовать дополнительные блоки. Если использовать все блоки описанные в статье, то код будет выглядеть так:
try:
# попробуем что-то сделать
except (ZeroDivisionError, ValueError) as e:
# обрабатываем исключения типа ZeroDivisionError или ValueError
except Exception as e:
# исключение не ZeroDivisionError и не ValueError
# поэтому обрабатываем исключение общего типа (унаследованное от Exception)
# сюда не сходят исключения типа GeneratorExit, KeyboardInterrupt, SystemExit
else:
# этот блок выполняется, если нет исключений
# если в этом блоке сделать return, он не будет вызван, пока не выполнился блок finally
finally:
# этот блок выполняется всегда, даже если нет исключений else будет проигнорирован
# если в этом блоке сделать return, то return в блоке
Подробнее о работе с исключениями в Python можно ознакомиться в официальной документации.
Мы можем использовать блок try-except, чтобы перехватывать исключения и обрабатывать их. Иногда мы вызываем функцию, которая может вызывать несколько типов исключений в зависимости от аргументов, логики обработки исключений Python и т.д. В этом руководстве мы узнаем, как перехватить несколько исключений в python.
Допустим, у нас есть функция, определенная следующим образом:
import math def square(x): if int(x) is 0: raise ValueError('Input argument cannot be zero') if int(x) < 0: raise TypeError('Input argument must be positive integer') return math.pow(int(x), 2)
Мы можем поймать, как ValueError, так и TypeError в разных блоках except.
while True: try: y = square(input('Please enter a numbern')) print(y) except ValueError as ve: print(type(ve), '::', ve) except TypeError as te: print(type(te), '::', te)
Я поместил блок try-except в цикл while True, чтобы я мог запустить сценарий перехвата нескольких исключений.
Вывод:
Please enter a number 10 100.0 Please enter a number -5 <class 'TypeError'> :: Input argument must be positive integer Please enter a number 0 <class 'ValueError'> :: Input argument cannot be zero Please enter a number ^D Traceback (most recent call last): File "/Users/pankaj/Documents/github/journaldev/Python-3/basic_examples/python_catch_multiple_exceptions.py", line 15, in y = square(input('Please enter a numbern')) EOFError: EOF when reading a line Process finished with exit code 1
Если вы заметили код блока except, он одинаков для обоих типов исключений Python. В этом случае мы можем удалить избыточность кода, передав кортеж типов исключений в блоке except.
Вот переписанный выше код, в котором мы перехватываем несколько исключений в одном блоке except.
while True: try: y = square(input('Please enter a numbern')) print(y) except (ValueError, TypeError) as e: print(type(e), '::', e)
Результат будет таким же, как и раньше. Мы можем использовать этот подход, когда код в блоке except одинаков для нескольких пойманных исключений.
( 5 оценок, среднее 2.6 из 5 )
Помогаю в изучении Питона на примерах. Автор практических задач с детальным разбором их решений.
In this tutorial we will learn all about handling errors and exceptions in Python programming using try..except
block.
Python built-in exceptions
Before we start with try..except
block, let us go through some of the in-built exceptions from Python. Python ships with a ton of built-in exception classes to cover a lot of error situations so that you do not have to define your own. These classes are divided into Base error classes, from which other error classes are defined, and Concrete error classes, which define the exceptions you are more likely to see from time to time.
Following are some of the common error and exception classes:
- SyntaxError: It occurs when you type a line of code which the Python interpreter is unable to parse
- ImportError: It occurs when an import cannot be resolved.
- KeyError: It occurs when a dictionary key is not found while trying to access it
- TypeError: It occurs if you attempt to do an operation on a value or object of the wrong type
- AttributeError: It is raised when assigning or referencing an attribute fails.
- IndexError: It occurs if you are trying to access an index (for example, in a list) which does not exist.
- NameError: It occurs when a specified name cannot be found either locally or globally
- FileNotFoundError: This error is raised if a file you are attempting to read or write is not found
ALSO READ: Deploy flask with gunicorn and nginx (Step-by-Step)
Handling Errors and Exceptions
Python uses special objects called exceptions to manage errors that arise during a program’s execution. Whenever an error occurs that makes Python unsure what to do next, it creates an exception object. If you write code that handles the exception, the program will continue running. If you don’t handle the exception, the program will halt and show a traceback, which includes a report of the exception that was raised.
Different try statement clauses
When you write a try
statement, a variety of clauses can appear after the try header. Below summarizes all the possible forms which we will cover in this tutorial.
Clause Form | Interpretation |
---|---|
except: |
Catch all (or all other) exception types. |
except <em>name:</em> |
Catch a specific exception only. |
except <em>name</em> as <em>value</em>: |
Catch the listed exception and assign its instance. |
except (<em>name1</em>, <em>name2</em>): |
except (name1, name2): |
except (<em>name1</em>, <em>name2</em>) as <em>value</em>: |
Catch any listed exception and assign its instance. |
else: |
Run if no exceptions are raised in the try block. |
finally: |
Always perform this block on exit. |
try..except block
Exceptions are handled with try-except blocks. A try-except block asks Python to do something, but it also tells Python what to do if an exception is raised. When you use try-except blocks, your programs will continue running even if things start to go wrong. Instead of tracebacks, which can be confusing for users to read, users will see friendly error messages that you write.
ALSO READ: Install Python Package from Github [Linux and Windows]
Syntax
The basic syntax to use try..except
blocks would be:
try: # do something here except [Exception]: # If there is Exception, then execute this block.
You can define multiple exception blocks to handle different kind of exceptions. We will cover this using different examples to help you understand better.
Example-1: Handling single exception
Before I handle exceptions, let me show you a general scenario where the script can fail while trying to open a file but the file does not exist. In such case you would get FileNotFoundError
exception and the worst part is any code after this exception will not be executed
#!/usr/bin/env python3 with open('input.txt', 'r') as myfile: for line in myfile: print(line) print('Outside the with block')
Output from this script:
As expected we are getting FileNotFoundError
exception. So we will handle this by using try..except
block:
#!/usr/bin/env python3 try: with open('input.txt', 'r') as myfile: for line in myfile: print(line) except: print('Sorry, file doesn't exist') print('Outside the with block')
I have updated the code, although I have not defined the type of exception and have used a generic except block so for any kind of error I would get «Sorry, file doesn't exist
«
Output from this script:
ALSO READ: 10 easy & useful examples to learn Python enum class
So now we don’t get any exception and our print statement outside the with
block is also executed.
Example-2: Provide the type of exception
As I mentioned earlier, in the previous example I have not defined the type of exception so for any kind of issue, I will get the same message which can be misleading. For example the file exist although the user is not having enough permission to access the file and still I would get same message.
For the demonstration, I am using a normal user to execute the same script. I have created input.txt as root user and have given only 600
permission so user ‘deepak
‘ has no permission to read this file
[deepak@server ~]$ ls -l input.txt
-rw------- 1 root root 0 Oct 15 14:49 input.txt
Now I execute the same script from Example-1:
[deepak@server ~]$ python3 handle-exceptions.py
Sorry, file doesn't exist
Outside the with block
We still get «Sorry, file doesn't exist
» which is misleading because the file is actually there but I don’t have permission to access the file.
To handle such situation we can define the Exception Type with except block:
#!/usr/bin/env python3 try: with open('input.txt', 'r') as myfile: for line in myfile: print(line) except FileNotFoundError: print('Sorry, file doesn't exist') except PermissionError: print('Sorry, you don't have permission to access the file') print('Outside the with block')
So now I have enhanced the script to handle two separate exceptions for FileNotFoundError
and PermissionError
.
Output from this script:
ALSO READ: SOLVED: Calling a function from another file in Python
Example-3: Define multiple exceptions in single block
In the previous example we defined separate block for individual exceptions. We can also combine all the applicable exceptions in single except
block. For example I have combined FileNotFoundError
and PermissionError
into single except block and given a more precise print
statement:
#!/usr/bin/env python3 try: with open('input.txt', 'r') as myfile: for line in myfile: print(line) except (FileNotFoundError, PermissionError): print('Sorry, file doesn't exist or you don't have permission to access the file') print('Outside the with block')
Output from this script:
So using this approach saved few lines of code.
Example-4: Using a generic exception block
Now we have covered some scenarios where we have manually defined the exception type, but there is also a possibility wherein the exception type doesn’t match the ones which we have added in the code in which case it is always a good idea to also add except Exception
to handle unforeseen issues. Additionally we can store the output into a variable and then print that variable as the output.
I have updated our script with except Exception
block to handle any other exceptions which are not defined in the code and storing the output into error
variable, later I will print the content of this variable:
#!/usr/bin/env python3 try: with open('input.txt', 'r') as myfile: for line in myfile: print(line) except FileNotFoundError: print('Sorry, file doesn't exist or you don't have permission to access the file') except Exception as error: print(error) print(type(error)) print('Outside the with block')
Output from this script:
ALSO READ: 4 ways to add row to existing DataFrame in Pandas
try..except..else block
The try…except…else
block is a minor modification of the traditional try…except
block so that it can include an else
block.
Syntax
The syntax for try..except..else
block would be:
try: # do something here except [Exception]: # If there is Exception, then execute this block. else: # If there are no exceptions then execute this block
The code in the else
block is always executed if no error has occurred. So, any code that depends on the try
block executing successfully goes in the else
block:
Example: Using try with else block
In this sample script we will prompt user for two numbers and using the python code we will divide first number by the second number
Output from this script:
~]$ python3 handle-exceptions.py Give me two numbers Enter 'q' to quit First number: 10 Second number: 5 You get: 2.0 First number: 10 Second number: 0 Traceback (most recent call last): File "handle-exceptions.py", line 13, in answer = int(first_num) / int(second_num) ZeroDivisionError: division by zero
So if we try to divide the «first number» by 0 then we get ZeroDivisionError
exception. Let me try to handle ZeroDivisionError
with except and else block:
#!/usr/bin/env python3 print("Give me two numbers") print("Enter 'q' to quit") while True: first_num = input("nFirst number: ") if first_num == 'q': break second_num = input("Second number: ") if second_num == 'q': break try: answer = int(first_num) / int(second_num) except ZeroDivisionError: print("You can not divide by 0") else: print('You get: ', answer)
Output from this script:
ALSO READ: Python static method Explained [Practical Examples]
So now the else
block is executed for all the SUCCESS condition and except block will handle the ZeroDivisionError
exception.
try..finally block
We use try..finally
when you want exceptions to propagate up but also want to run cleanup code even when exceptions occur. One common usage of try..finally
is for reliably closing file handles
Syntax
The syntax to use try..except..finally
block would be. The except block is optional and you can also use try..finally
without except
block.
try: # do something here except [Exception]: # If there is Exception, then execute this block. finally: # This is executed always
If you wish to combine else
block then the order of the statement should be:
try -> except -> else -> finally
Example-1: Using try with finally block
I will take a simple example to help you understand the usage of try..finally
block. Here we will prompt user for an input with an integer, next we will divide 100 with this number and store the result in re
.
- Now if an exception is raised then we go into
except
block - If there are no exceptions then
else
block is executed - Irrespective of exceptions, the
finally
block will always be executed
#!/usr/bin/env python3 try: num = int(input("Enter the number: ")) re = 100/num except: print("Something is wrong") else: print("result is ",re) finally : print("finally program ends") print('END')
Output from this script (with no exceptions):
~]$ python3 try-finally.py
Enter the number: 10
result is 10.0
finally program ends
END
Output from this script (with exceptions):
~]$ python3 try-finally.py
Enter the number: abcd
Something is wrong
finally program ends
END
So in both the scenarios, the finally
block was executed.
ALSO READ: 7+ simple examples to learn python range() function
Example-2: Open and close file handle using try..finally block
This is a more practical example where we are opening a file to perform some read and write operation and intentionally we will try to write invalid utf-8 content which will raise UnicodeDecodeError
in which case the finally
block will execute and close the file handle.
NOTE:
You must call open
before the try
block because exceptions that occur when opening the file (like OSError
if the file does not exist) should skip the finally block entirely:
Output from this script:
~]$ python3 try-finally.py * Opening file * Reading data * Calling close() Traceback (most recent call last): File "try-finally.py", line 11, in handle.read() # Maybe UnicodeDecodeError File "/usr/lib64/python3.6/codecs.py", line 321, in decode (result, consumed) = self._buffer_decode(data, self.errors, final) UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf1 in position 0: invalid continuation byte
So even though we have received an exception, our code from finally
block was executed to close the file handle.
Manually raise exceptions
To trigger exceptions explicitly, you can code raise statements. Their general form is simple—a raise statement consists of the word raise, optionally followed by the class to be raised or an instance of it:
Syntax:
raise instance # Raise instance of class raise class # Make and raise instance of class: makes an instance raise # Reraise the most recent exception
For example here we have a simple if else condition. If the condition matches then we print something on the console and for else condition we will raise ValueError
with some custom message:
#!/usr/bin/env python3 num = int(input('Enter any number: ')) mylist = [10, 21, 34, 49, 52] if num in mylist: print('Bingo, you hit the jackpot') else: raise ValueError('Ohh, you missed the jackpot')
Output from this script:
~]$ python3 raise-exceptions-1.py Enter any number: 20 Traceback (most recent call last): File "raise-exceptions-1.py", line 9, in raise ValueError('Ohh, you missed the jackpot') ValueError: Ohh, you missed the jackpot
As you see, since the provided number was not part of the mylist
, ValueError
is raised as we had defined. So using raise we can manually create exceptions within python code.
ALSO READ: 10+ simple examples to learn python sets in detail
Define and raise custom exceptions
Built-in exceptions cover a wide range of situations. Sometimes, however, you may need to define a custom exception to fit your specific application situation; for example, a MyCustomError
exception.
In this case, Python contains the ability to add custom errors by extending the base Exception class. We will use our existing example and instead of ValueError
, we will create our own exception and execute it inside the else block:
Output from this script when we provide a number which is not present in the list:
~]$ python3 raise-exceptions-1.py Enter any number: 20 Traceback (most recent call last): File "raise-exceptions-1.py", line 12, in raise MyCustomError('Ohh, you missed the jackpot') __main__.MyCustomError: Ohh, you missed the jackpot
The assert statement
Python includes the assert
statement. The next step toward creating real tests is to assert that a particular comparison holds true. Assertions are typically used to verify program conditions during development. For example, here I am using assert to perform the comparison instead of if condition and raising an exception if condition is not matched
#!/usr/bin/env python3 class MyCustomError(Exception): pass num = int(input('Enter any number: ')) mylist = [10, 21, 34, 49, 52] try: assert num in mylist print('Bingo, you hit the jackpot') except: print('Ohh, you missed the jackpot')
Output from this script:
~]$ python3 raise-exceptions-1.py
Enter any number: 20
Ohh, you missed the jackpot
Since the assert
condition didn’t matched, the except block was executed.
ALSO READ: Hackerrank Solution: Map and lambda function in Python
Conclusion
In this tutorial, we talked about errors and exceptions, what they are, and how to avoid them. We looked at a few built-in errors and the scenarios that would cause them to be raised. We then moved on to handling them by using try…except
and finally blocks. We also covered how to implement our own custom exceptions by using the Exception base class.
This should give you the ability to make your programs more robust by handling both seen and unforeseen issues that may arise during code execution. Handling errors should also help prevent unpleasant usability or security issues from cropping up when your code is in the wild.