Обработка ошибок увеличивает отказоустойчивость кода, защищая его от потенциальных сбоев, которые могут привести к преждевременному завершению работы.
Прежде чем переходить к обсуждению того, почему обработка исключений так важна, и рассматривать встроенные в Python исключения, важно понять, что есть тонкая грань между понятиями ошибки и исключения.
Ошибку нельзя обработать, а исключения Python обрабатываются при выполнении программы. Ошибка может быть синтаксической, но существует и много видов исключений, которые возникают при выполнении и не останавливают программу сразу же. Ошибка может указывать на критические проблемы, которые приложение и не должно перехватывать, а исключения — состояния, которые стоит попробовать перехватить. Ошибки — вид непроверяемых и невозвратимых ошибок, таких как OutOfMemoryError
, которые не стоит пытаться обработать.
Обработка исключений делает код более отказоустойчивым и помогает предотвращать потенциальные проблемы, которые могут привести к преждевременной остановке выполнения. Представьте код, который готов к развертыванию, но все равно прекращает работу из-за исключения. Клиент такой не примет, поэтому стоит заранее обработать конкретные исключения, чтобы избежать неразберихи.
Ошибки могут быть разных видов:
- Синтаксические
- Недостаточно памяти
- Ошибки рекурсии
- Исключения
Разберем их по очереди.
Синтаксические ошибки (SyntaxError)
Синтаксические ошибки часто называют ошибками разбора. Они возникают, когда интерпретатор обнаруживает синтаксическую проблему в коде.
Рассмотрим на примере.
a = 8
b = 10
c = a b
File "", line 3
c = a b
^
SyntaxError: invalid syntax
Стрелка вверху указывает на место, где интерпретатор получил ошибку при попытке исполнения. Знак перед стрелкой указывает на причину проблемы. Для устранения таких фундаментальных ошибок Python будет делать большую часть работы за программиста, выводя название файла и номер строки, где была обнаружена ошибка.
Недостаточно памяти (OutofMemoryError)
Ошибки памяти чаще всего связаны с оперативной памятью компьютера и относятся к структуре данных под названием “Куча” (heap
). Если есть крупные объекты (или) ссылки на подобные, то с большой долей вероятности возникнет ошибка OutofMemory
. Она может появиться по нескольким причинам:
- Использование 32-битной архитектуры Python (максимальный объем выделенной памяти невысокий, между 2 и 4 ГБ);
- Загрузка файла большого размера;
- Запуск модели машинного обучения/глубокого обучения и много другое;
Обработать ошибку памяти можно с помощью обработки исключений — резервного исключения. Оно используется, когда у интерпретатора заканчивается память и он должен немедленно остановить текущее исполнение. В редких случаях Python вызывает OutofMemoryError
, позволяя скрипту каким-то образом перехватить самого себя, остановить ошибку памяти и восстановиться.
Но поскольку Python использует архитектуру управления памятью из языка C (функция malloc()
), не факт, что все процессы восстановятся — в некоторых случаях MemoryError
приведет к остановке. Следовательно, обрабатывать такие ошибки не рекомендуется, и это не считается хорошей практикой.
Ошибка рекурсии (RecursionError)
Эта ошибка связана со стеком и происходит при вызове функций. Как и предполагает название, ошибка рекурсии возникает, когда внутри друг друга исполняется много методов (один из которых — с бесконечной рекурсией), но это ограничено размером стека.
Все локальные переменные и методы размещаются в стеке. Для каждого вызова метода создается стековый кадр (фрейм), внутрь которого помещаются данные переменной или результат вызова метода. Когда исполнение метода завершается, его элемент удаляется.
Чтобы воспроизвести эту ошибку, определим функцию recursion
, которая будет рекурсивной — вызывать сама себя в бесконечном цикле. В результате появится ошибка StackOverflow
или ошибка рекурсии, потому что стековый кадр будет заполняться данными метода из каждого вызова, но они не будут освобождаться.
def recursion():
return recursion()
recursion()
---------------------------------------------------------------------------
RecursionError Traceback (most recent call last)
in
----> 1 recursion()
in recursion()
1 def recursion():
----> 2 return recursion()
... last 1 frames repeated, from the frame below ...
in recursion()
1 def recursion():
----> 2 return recursion()
RecursionError: maximum recursion depth exceeded
Ошибка отступа (IndentationError)
Эта ошибка похожа по духу на синтаксическую и является ее подвидом. Тем не менее она возникает только в случае проблем с отступами.
Пример:
for i in range(10):
print('Привет Мир!')
File "", line 2
print('Привет Мир!')
^
IndentationError: expected an indented block
Исключения
Даже если синтаксис в инструкции или само выражение верны, они все равно могут вызывать ошибки при исполнении. Исключения Python — это ошибки, обнаруживаемые при исполнении, но не являющиеся критическими. Скоро вы узнаете, как справляться с ними в программах Python. Объект исключения создается при вызове исключения Python. Если скрипт не обрабатывает исключение явно, программа будет остановлена принудительно.
Программы обычно не обрабатывают исключения, что приводит к подобным сообщениям об ошибке:
Ошибка типа (TypeError)
a = 2
b = 'PythonRu'
a + b
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
in
1 a = 2
2 b = 'PythonRu'
----> 3 a + b
TypeError: unsupported operand type(s) for +: 'int' and 'str'
Ошибка деления на ноль (ZeroDivisionError)
10 / 0
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
in
----> 1 10 / 0
ZeroDivisionError: division by zero
Есть разные типы исключений в Python и их тип выводится в сообщении: вверху примеры TypeError
и ZeroDivisionError
. Обе строки в сообщениях об ошибке представляют собой имена встроенных исключений Python.
Оставшаяся часть строки с ошибкой предлагает подробности о причине ошибки на основе ее типа.
Теперь рассмотрим встроенные исключения Python.
Встроенные исключения
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StopAsyncIteration
+-- ArithmeticError
| +-- FloatingPointError
| +-- OverflowError
| +-- ZeroDivisionError
+-- AssertionError
+-- AttributeError
+-- BufferError
+-- EOFError
+-- ImportError
| +-- ModuleNotFoundError
+-- LookupError
| +-- IndexError
| +-- KeyError
+-- MemoryError
+-- NameError
| +-- UnboundLocalError
+-- OSError
| +-- BlockingIOError
| +-- ChildProcessError
| +-- ConnectionError
| | +-- BrokenPipeError
| | +-- ConnectionAbortedError
| | +-- ConnectionRefusedError
| | +-- ConnectionResetError
| +-- FileExistsError
| +-- FileNotFoundError
| +-- InterruptedError
| +-- IsADirectoryError
| +-- NotADirectoryError
| +-- PermissionError
| +-- ProcessLookupError
| +-- TimeoutError
+-- ReferenceError
+-- RuntimeError
| +-- NotImplementedError
| +-- RecursionError
+-- SyntaxError
| +-- IndentationError
| +-- TabError
+-- SystemError
+-- TypeError
+-- ValueError
| +-- UnicodeError
| +-- UnicodeDecodeError
| +-- UnicodeEncodeError
| +-- UnicodeTranslateError
+-- Warning
+-- DeprecationWarning
+-- PendingDeprecationWarning
+-- RuntimeWarning
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
+-- ImportWarning
+-- UnicodeWarning
+-- BytesWarning
+-- ResourceWarning
Прежде чем переходить к разбору встроенных исключений быстро вспомним 4 основных компонента обработки исключения, как показано на этой схеме.
Try
: он запускает блок кода, в котором ожидается ошибка.Except
: здесь определяется тип исключения, который ожидается в блокеtry
(встроенный или созданный).Else
: если исключений нет, тогда исполняется этот блок (его можно воспринимать как средство для запуска кода в том случае, если ожидается, что часть кода приведет к исключению).Finally
: вне зависимости от того, будет ли исключение или нет, этот блок кода исполняется всегда.
В следующем разделе руководства больше узнаете об общих типах исключений и научитесь обрабатывать их с помощью инструмента обработки исключения.
Ошибка прерывания с клавиатуры (KeyboardInterrupt)
Исключение KeyboardInterrupt
вызывается при попытке остановить программу с помощью сочетания Ctrl + C
или Ctrl + Z
в командной строке или ядре в Jupyter Notebook. Иногда это происходит неумышленно и подобная обработка поможет избежать подобных ситуаций.
В примере ниже если запустить ячейку и прервать ядро, программа вызовет исключение KeyboardInterrupt
. Теперь обработаем исключение KeyboardInterrupt
.
try:
inp = input()
print('Нажмите Ctrl+C и прервите Kernel:')
except KeyboardInterrupt:
print('Исключение KeyboardInterrupt')
else:
print('Исключений не произошло')
Исключение KeyboardInterrupt
Стандартные ошибки (StandardError)
Рассмотрим некоторые базовые ошибки в программировании.
Арифметические ошибки (ArithmeticError)
- Ошибка деления на ноль (Zero Division);
- Ошибка переполнения (OverFlow);
- Ошибка плавающей точки (Floating Point);
Все перечисленные выше исключения относятся к классу Arithmetic
и вызываются при ошибках в арифметических операциях.
Деление на ноль (ZeroDivisionError)
Когда делитель (второй аргумент операции деления) или знаменатель равны нулю, тогда результатом будет ошибка деления на ноль.
try:
a = 100 / 0
print(a)
except ZeroDivisionError:
print("Исключение ZeroDivisionError." )
else:
print("Успех, нет ошибок!")
Исключение ZeroDivisionError.
Переполнение (OverflowError)
Ошибка переполнение вызывается, когда результат операции выходил за пределы диапазона. Она характерна для целых чисел вне диапазона.
try:
import math
print(math.exp(1000))
except OverflowError:
print("Исключение OverFlow.")
else:
print("Успех, нет ошибок!")
Исключение OverFlow.
Ошибка утверждения (AssertionError)
Когда инструкция утверждения не верна, вызывается ошибка утверждения.
Рассмотрим пример. Предположим, есть две переменные: a
и b
. Их нужно сравнить. Чтобы проверить, равны ли они, необходимо использовать ключевое слово assert
, что приведет к вызову исключения Assertion
в том случае, если выражение будет ложным.
try:
a = 100
b = "PythonRu"
assert a == b
except AssertionError:
print("Исключение AssertionError.")
else:
print("Успех, нет ошибок!")
Исключение AssertionError.
Ошибка атрибута (AttributeError)
При попытке сослаться на несуществующий атрибут программа вернет ошибку атрибута. В следующем примере можно увидеть, что у объекта класса Attributes
нет атрибута с именем attribute
.
class Attributes(obj):
a = 2
print(a)
try:
obj = Attributes()
print(obj.attribute)
except AttributeError:
print("Исключение AttributeError.")
2
Исключение AttributeError.
Ошибка импорта (ModuleNotFoundError)
Ошибка импорта вызывается при попытке импортировать несуществующий (или неспособный загрузиться) модуль в стандартном пути или даже при допущенной ошибке в имени.
import nibabel
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
in
----> 1 import nibabel
ModuleNotFoundError: No module named 'nibabel'
Ошибка поиска (LookupError)
LockupError
выступает базовым классом для исключений, которые происходят, когда key
или index
используются для связывания или последовательность списка/словаря неверна или не существует.
Здесь есть два вида исключений:
- Ошибка индекса (
IndexError
); - Ошибка ключа (
KeyError
);
Ошибка ключа
Если ключа, к которому нужно получить доступ, не оказывается в словаре, вызывается исключение KeyError
.
try:
a = {1:'a', 2:'b', 3:'c'}
print(a[4])
except LookupError:
print("Исключение KeyError.")
else:
print("Успех, нет ошибок!")
Исключение KeyError.
Ошибка индекса
Если пытаться получить доступ к индексу (последовательности) списка, которого не существует в этом списке или находится вне его диапазона, будет вызвана ошибка индекса (IndexError: list index out of range python).
try:
a = ['a', 'b', 'c']
print(a[4])
except LookupError:
print("Исключение IndexError, индекс списка вне диапазона.")
else:
print("Успех, нет ошибок!")
Исключение IndexError, индекс списка вне диапазона.
Ошибка памяти (MemoryError)
Как уже упоминалось, ошибка памяти вызывается, когда операции не хватает памяти для выполнения.
Ошибка имени (NameError)
Ошибка имени возникает, когда локальное или глобальное имя не находится.
В следующем примере переменная ans
не определена. Результатом будет ошибка NameError
.
try:
print(ans)
except NameError:
print("NameError: переменная 'ans' не определена")
else:
print("Успех, нет ошибок!")
NameError: переменная 'ans' не определена
Ошибка выполнения (Runtime Error)
Ошибка «NotImplementedError»
Ошибка выполнения служит базовым классом для ошибки NotImplemented
. Абстрактные методы определенного пользователем класса вызывают это исключение, когда производные методы перезаписывают оригинальный.
class BaseClass(object):
"""Опередляем класс"""
def __init__(self):
super(BaseClass, self).__init__()
def do_something(self):
# функция ничего не делает
raise NotImplementedError(self.__class__.__name__ + '.do_something')
class SubClass(BaseClass):
"""Реализует функцию"""
def do_something(self):
# действительно что-то делает
print(self.__class__.__name__ + ' что-то делает!')
SubClass().do_something()
BaseClass().do_something()
SubClass что-то делает!
---------------------------------------------------------------------------
NotImplementedError Traceback (most recent call last)
in
14
15 SubClass().do_something()
---> 16 BaseClass().do_something()
in do_something(self)
5 def do_something(self):
6 # функция ничего не делает
----> 7 raise NotImplementedError(self.__class__.__name__ + '.do_something')
8
9 class SubClass(BaseClass):
NotImplementedError: BaseClass.do_something
Ошибка типа (TypeError)
Ошибка типа вызывается при попытке объединить два несовместимых операнда или объекта.
В примере ниже целое число пытаются добавить к строке, что приводит к ошибке типа.
try:
a = 5
b = "PythonRu"
c = a + b
except TypeError:
print('Исключение TypeError')
else:
print('Успех, нет ошибок!')
Исключение TypeError
Ошибка значения (ValueError)
Ошибка значения вызывается, когда встроенная операция или функция получают аргумент с корректным типом, но недопустимым значением.
В этом примере встроенная операция float
получат аргумент, представляющий собой последовательность символов (значение), что является недопустимым значением для типа: число с плавающей точкой.
try:
print(float('PythonRu'))
except ValueError:
print('ValueError: не удалось преобразовать строку в float: 'PythonRu'')
else:
print('Успех, нет ошибок!')
ValueError: не удалось преобразовать строку в float: 'PythonRu'
Пользовательские исключения в Python
В Python есть много встроенных исключений для использования в программе. Но иногда нужно создавать собственные со своими сообщениями для конкретных целей.
Это можно сделать, создав новый класс, который будет наследовать из класса Exception
в Python.
class UnAcceptedValueError(Exception):
def __init__(self, data):
self.data = data
def __str__(self):
return repr(self.data)
Total_Marks = int(input("Введите общее количество баллов: "))
try:
Num_of_Sections = int(input("Введите количество разделов: "))
if(Num_of_Sections < 1):
raise UnAcceptedValueError("Количество секций не может быть меньше 1")
except UnAcceptedValueError as e:
print("Полученная ошибка:", e.data)
Введите общее количество баллов: 10
Введите количество разделов: 0
Полученная ошибка: Количество секций не может быть меньше 1
В предыдущем примере если ввести что-либо меньше 1, будет вызвано исключение. Многие стандартные исключения имеют собственные исключения, которые вызываются при возникновении проблем в работе их функций.
Недостатки обработки исключений в Python
У использования исключений есть свои побочные эффекты, как, например, то, что программы с блоками try-except работают медленнее, а количество кода возрастает.
Дальше пример, где модуль Python timeit
используется для проверки времени исполнения 2 разных инструкций. В stmt1
для обработки ZeroDivisionError
используется try-except, а в stmt2
— if
. Затем они выполняются 10000 раз с переменной a=0
. Суть в том, чтобы показать разницу во времени исполнения инструкций. Так, stmt1
с обработкой исключений занимает больше времени чем stmt2
, который просто проверяет значение и не делает ничего, если условие не выполнено.
Поэтому стоит ограничить использование обработки исключений в Python и применять его в редких случаях. Например, когда вы не уверены, что будет вводом: целое или число с плавающей точкой, или не уверены, существует ли файл, который нужно открыть.
import timeit
setup="a=0"
stmt1 = '''
try:
b=10/a
except ZeroDivisionError:
pass'''
stmt2 = '''
if a!=0:
b=10/a'''
print("time=",timeit.timeit(stmt1,setup,number=10000))
print("time=",timeit.timeit(stmt2,setup,number=10000))
time= 0.003897680000136461
time= 0.0002797570000439009
Выводы!
Как вы могли увидеть, обработка исключений помогает прервать типичный поток программы с помощью специального механизма, который делает код более отказоустойчивым.
Обработка исключений — один из основных факторов, который делает код готовым к развертыванию. Это простая концепция, построенная всего на 4 блоках: try
выискивает исключения, а except
их обрабатывает.
Очень важно поупражняться в их использовании, чтобы сделать свой код более отказоустойчивым.
Today seems to be a fine day to learn about KeyboardInterrupt. If you read this article, I can deduce that you have some proficiency with exceptions and exception handling. Don’t sweat it even if you have no knowledge about them; we will give you a brief refresher.
Exceptions are errors that may interrupt the flow of your code and end it prematurely; before even completing its execution. Python has numerous built-in exceptions which inherit from the BaseException class. Check all built-in exceptions from here.
Try-catch blocks handle exceptions, for instance:
try: div_by_zero = 10/0 except Exception as e: print(f"Exception name:{e}") else: print("I would have run if there wasn't any exception") finally: print("I will always run!")
The big idea is to keep that code into a try block which may throw an exception. Except block will catch that exception and do something(statements defined by the user). Finally, block always gets executed, generally used for handling external resources. For instance, database connectivity, closing a file, etc. If there isn’t any exception, code in the else block will also run.
What is Keyboard Interrupt Exception?
KeyboardInterrupt exception is a part of Python’s built-in exceptions. When the programmer presses the ctrl + c or ctrl + z command on their keyboards, when present in a command line(in windows) or in a terminal(in mac os/Linux), this abruptly ends the program amidst execution.
Looping until Keyboard Interrupt
count = 0 whilte True: print(count) count += 1
Try running this code on your machine.
An infinite loop begins, printing and incrementing the value of count. Ctrl + c keyboard shortcut; will interrupt the program. For this reason, program execution comes to a halt. A KeyboardInterrupt message is shown on the screen.
Python interpreter keeps a watch for any interrupts while executing the program. It throws a KeyboardInterrupt exception whenever it detects the keyboard shortcut Ctrl + c. The programmer might have done this intentionally or unknowingly.
Catching/Handling KeyboardInterrupt
try: while True: print("Program is running") except KeyboardInterrupt: print("Oh! you pressed CTRL + C.") print("Program interrupted.") finally: print("This was an important code, ran at the end.")
Try-except block handles keyboard interrupt exception easily.
- In the try block a infinite while loop prints following line- “Program is running”.
- On pressing ctrl + c, python interpretor detects an keyboard interrupt and halts the program mid execution.
- After that, finally block finishes its execution.
Catching KeyboardInterrupt using Signal module
Signal handlers of the signal library help perform specific tasks whenever a signal is detected.
import signal import sys import threading def signal_handler(signal, frame): print('nYou pressed Ctrl+C, keyboardInterrupt detected!') sys.exit(0) signal.signal(signal.SIGINT, signal_handler) print('Enter Ctrl+C to initiate keyboard iterrupt:') forever_wait = threading.Event() forever_wait.wait()
Let’s breakdown the code given above:
- SIGINT reperesents signal interrupt. The terminal sends to the process whenever programmer wants to interrupt it.
- forever_wait event waits forever for a ctrl + c signal from keyboard.
- signal_handler function on intercepting keyboard interrupt signal will exit the process using sys.exit.
Subprocess KeyboardInterrupt
A subprocess in Python is a task that a python script assigns to the Operative system (OS).
process.py
while True: print(f"Program {__file__} running..")
test.py
import sys from subprocess import call try: call([sys.executable, 'process.py'], start_new_session=True) except KeyboardInterrupt: print('[Ctrl C],KeyboardInterrupt exception occured.') else: print('No exception')
Let’s understand the working of the above codes:
- We have two files, namely, process.py and test.py. In the process.py file, there is an infinite while loop which prints “Program sub_process.py running”.
- In the try block sys.executeble gives the path to python interpretor to run our subprocess which is process.py.
- On pressing ctrl + c, python interpretor detects an keyboard interrupt and halts the program mid execution. Later handled by the except block.
FAQs on KeyboardInterrupt
How to prevent traceback on keyboard interrupt?
To prevent traceback from popping up, you need to handle the KeyboardInterrupt exception in the except block.try:
while True:
print("Running program…")
except KeyboardInterrupt:
print("caught keyboard interrupt")
KeyboardInterrupt in jupyter notebook
If a cell block takes too much time to execute, click on the kernel option, then restart the kernel 0,0 option.
Flask keyboard interrupt, closing flask application?
When using the flask framework use these functions.
Windows : netstat -ano | findstr
Linux: netstat -nlp | grep
macOS: lsof -P -i :
Interrupt in multiprocessing pool?
This is a Python bug. When waiting for a condition in threading.Condition.wait(), KeyboardInterrupt is never sent.import threading
cond = threading.Condition(threading.Lock()) cond.acquire()
cond.wait(None) print "done"
Conclusion
This article briefly covered topics like exceptions, try-catch blocks, usage of finally, and else. We also learned how keyboard interrupt could abruptly halt the flow of the program. Programmers can use it to exit a never-ending loop or meet a specific condition. We also covered how to handle keyboard interrupt using try-except block in Python. Learned about another way to catch keyboard interrupt exception and interrupted a subprocess.
Trending Python Articles
-
“Other Commands Don’t Work After on_message” in Discord Bots
●February 5, 2023
-
Botocore.Exceptions.NoCredentialsError: Unable to Locate Credentials
by Rahul Kumar Yadav●February 5, 2023
-
[Resolved] NameError: Name _mysql is Not Defined
by Rahul Kumar Yadav●February 5, 2023
-
Best Ways to Implement Regex New Line in Python
by Rahul Kumar Yadav●February 5, 2023
Exceptions refer to the events of errors experienced when executing a program. This Python Exceptions tutorial will overview different exceptions in Python and explain how to catch and mitigate them.
Table of contents
What are the exceptions in Python?
Exceptions are events of failure in your Python code that result from database corruption, broken network connectivity, corrupted data, memory exhaustion, and unsupported user inputs. The purpose of every developer is to catch and mitigate such exceptions to ensure that the final program runs smoothly.
If an exception occurs when an application runs, there is a risk of losing data, corrupting existing data, or even causing the application to crash.
Python allows developers to handle these exceptions using pre-defined exceptions and structured exception handling.
For example, it is always possible to predict the possible error in a Python program and work around it by prompting the user to use the correct input, default value or alternate a program execution flow.
The difference between syntax errors and exceptions in Python
Syntax errors and exceptions in Python refer to unwanted conditions when executing a program.
Syntax error refers to an error that terminates the execution of a program due to the use of the wrong Python syntax in the code.
The wrong syntax comprises wrong naming styles, incorrect Python keywords, and invalid program structure.
Let’s take a look at the example below to illustrate the syntax error:
age = 18
def check_age(age):
if age >= 18
print("Individual is an adult")
If you try to execute the program above, you’ll get the following error message:
File "syntax_error_example.py", line 4
if age >= 18
^
SyntaxError: invalid syntax
On the other hand, exceptions refer to errors in executing a program, even when a statement is syntactically correct.
If the developer handles exceptions in the code, they do not stop the program’s execution but can lead to a change in the normal flow of the program execution.
As we’ve mentioned, it is possible to handle exceptions in your Python code so they might not be fatal and might not stop Python program execution.
We’ll take a look at how to handle exceptions later, but for now, let’s take a look at what happens if we’re not handling potentially dangerous situations in the code:
x = "test"
for i in range(x):
print(i)
Execution of the code block above will lead to the following error message and terminate program execution:
Traceback (most recent call last):
File "exception_example_1.py", line 3, in <module>
for i in range(x):
TypeError: 'str' object cannot be interpreted as an integer
Python3 Exception Handling
Now, it’s time to look at how to handle exceptions in Python.
Try block syntax in Python
To handle exceptions in Python, you need to use a try-except
block, which has the following syntax:
try:
statement(s)
except [exception_class]:
statement(s)
else:
statement(s)
finally:
statement(s)
Here’s how these clauses work:
- The
try
clause runs the block of code where an error is expected to occur. except
clause used to define the type of exception expected from thetry
block of code.- If there’s no exception captured, the
else
statemetns block is executed finally
statements are always to be executed regardless of any exceptions caught in thetry
clause
Catching a single exception in Python
Python allows you to handle any exceptions.
For example, let’s take a look at a program that prompts the user to enter a number, and when the program cannot convert the number to an integer, it raises a ValueError
exception:
for i in range(5):
x = input("Type in a number: ")
try:
number = int(x)
except ValueError:
print("The value you entered ({}) cannot be converted to an integer".format(x))
Now, let’s try to execute our program:
Type in a number: uytfd
The value you entered (uytfd) cannot be converted to an integer
Type in a number: 5656
Type in a number: 435
Type in a number: dfdf
The value you entered (dfdf) cannot be converted to an integer
Type in a number: shs
The value you entered (shs) cannot be converted to an integer
If the user is typing something wrong, the try
block will try to catch an exception by checking the exception classes provided in the except
clause.
If an exception doesn’t match any declared exceptions in the except
clause, Python will stop program execution with the message unhandled exception
.
Keep in mind: when handling exceptions in except blocks, a base class type will catch any raised type of its subclasses. For example, the ArythmeticError
exception class will catch OverflowError
, FloatingPointError
, and ZeroDivisionError
exceptions.
Catching multiple exceptions in Python
A try
clause can have to have several except
clauses to catch different types of exceptions for the same block of code:
for i in range(5):
try:
x = int(input("Type in a number: "))
except (ValueError, TypeError, NameError):
print("One of the above exceptions was captured during execution")
Here’s an execution output:
Type in a number: 675
Type in a number: jgd
One of the above exceptions wa captured during execution
Type in a number: fg
One of the above exceptions wa captured during execution
Type in a number: 56
Type in a number: 98
In addition to that, it is possible to provide several except
clauses to capture multiple exceptions:
for i in range(2):
user_input = input("Type in a number: ")
try:
x = int(user_input)
y = set()
y[1] = x
except ValueError:
print("The value you entered ({}) cannot be converted to an integer".format(user_input))
except TypeError:
print("You can not modify sets!!!")
print("Program execution finished")
Now, let’s try to execute the program above:
Type in a number: asd
The value you entered (asd) cannot be converted to an integer
Type in a number: 1
You can not modify sets!!!
Program execution finished
Even if we provide a valid value, we still have an error in the code, which was caught by the second except
clause.
Catching all exceptions in Python
Sometimes we do not know what exception we can get during the code execution, but we need to catch the error and continue the execution flow.
In that case, you can use except
clause without providing an exception name, but it is not recommended to hide any issues in the code block.
However, if you have a strong need, it is possible to catch any exception:
import os
path = "/not/existing/path"
try:
for file in os.listdir(path):
f = open(os.path.join(path, file))
except ValueError:
print("Catching ValueError")
except:
print("Unexpected error happened")
print("Program execution finished")
Here’s the execution output:
Unexpected error happened
Program execution finished
Using the “else” clause in the “try” block
If you’d like to know if the code block has been executed without any errors, you can use else
statement after the except
clauses:
for i in range(2):
x = input("Type in a number: ")
try:
number = int(x)
except ValueError:
print("The value you entered ({}) cannot be converted to an integer".format(x))
else:
print("Code block executed without issues")
print("Program execution finished")
Program execution result:
Type in a number: asf
The value you entered (asf) cannot be converted to an integer
Type in a number: 1
Code block executed without issues
Program execution finished
Getting access to the exception class in Python
If you need to get access to the exception class during the exception-handling process, you can do it by using as
keyword in the except
clause:
try:
a = 2/0
except Exception as error:
print(f'Exception info: {error.__doc__}')
Here’s an expected output:
Exception info: Second argument to a division or modulo operation was zero.
The difference between else and finally in Python
Lastly, let’s illustrate how else
and finally
clauses are working:
for i in [0, 1]:
try:
result = 2 / i
except ZeroDivisionError:
print("Division by zero")
else:
print(f'Division result: {result}')
finally:
print("Executing finally clausen")
print("Program execution finished")
Here’s an execution output:
Division by zero
Executing finally clause
Division result: 2.0
Executing finally clause
Program execution finished
As you can see from the program execution, Python always executes the finally
clause statements. At the same time, Python runs the else
clause statements only when try block executed without any errors.
Such behavior allows using the finally
clause to define clean-up actions such as closing sockets, file descriptors, disconnecting from the database, etc.
Your Python code should have these cleanup actions and execute them at all times, irrespective of the circumstances.
How to catch SyntaxErrorexception in Python
It is hard to catch the SyntaxError
exception, but it is still possible if the SyntaxError
is thrown out of an eval
, exec
, or import
statements:
try:
import my_module
except SyntaxError:
print("Syntax error in my_module")
print("Program execution finished")
Now, if the code in my_module
Python module contains syntax errors, program execution will not break:
Syntax error in my_module
Program execution finished
Raising exceptionsin Python
You have an opportunity not only to catch and workaround exceptions but also to raise them. So, if you’d like to throw an error in Python, use the raise
keyword followed by the error or exception type.
A common example of when you need this is implementing a manager class that allows users to allocate a network from a certain IP pool.
If the manager can’t allocate the network, it makes sense to create a user-defined exception and raise it when the event occurs.
To raise an exception in Python, you need to use raise
statement.
The exception you can raise can be any class that derives from an Exception
.
A python program implicitly instantiates the constructor by passing an exception class with no arguments, for example:
raise TypeError
As soon as Python runs the statement above, it will produce the following error message:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError
Re-raising exceptions in Python
In some cases, you may need to re-raise an exception that you’re capturing with try-except
block.
That’s possible by using a raise
statement without providing an exception class:
try:
raise TypeError(10.578)
except TypeError:
print('A float number was not captured!')
raise
The code above will not only raise an exception but also print the reason for that exception:
A float number was not captured!
Traceback (most recent call last):
File "rerising_exceptions.py", line 2, in <module>
raise TypeError(10.578)
TypeError: 10.578
Chaining exceptions in Python
Chaining exceptions is useful when you need to transform exceptions.
You can specify an optional from
keyword in the raise
statement that allows you to re-raise the exception and change its type:
def example():
try:
x = input("Type in a number: ")
number = int(x)
except ValueError as e:
raise RuntimeError('User input parsing error occurred') from e
example()
Here’s an execution output:
Type in a number: asd
Traceback (most recent call last):
File "multiple_except.py", line 4, in example
number = int(x)
ValueError: invalid literal for int() with base 10: 'asd'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "multiple_except.py", line 8, in <module>
example()
File "multiple_except.py", line 6, in example
raise RuntimeError('A parsing error occurred') from e
RuntimeError: A parsing error occurred
Built-In Python exceptions
Most of the built-in exceptions are inheriting the BaseException
class. Python interpreter usually generates these exceptions from built-in functions to help developers identify the root cause of an error during Python program execution.
You can inherit built-in exception classes to define new exceptions. All Python developers are encouraged to derive new exceptions from the Exception
class or one of its subclasses but not from the BaseException
class.
Base exception classes in Python
The tree of base exception classes provides Python developers with lots of standard exceptions. In this part of the article, we’ll review the purpose of Python3 exceptions.
BaseException
is the base class for all the built-in exceptions. Python developers should not directly inherit this class to define any custom exception classes. This class creates a string representation of the exception by defining the str() method and its arguments. If there are no arguments Python will return an exception with an empty string.GeneratorExit
Python throws this exception when a coroutine or generator is closed. It inherits from the BaseException but not the Exception class because it is not an error.KeyboardInterrupt
– When a user hits the interrupt key such as Delete or Control+C, this error exception is raised.SystemExit
– When thesys.exit()
function is called, this exception is raised. In addition, calling this function indicates that clean-up handlers should be executed, that is, thefinally
clauses oftry
statements.Exception
– is a base class for all built-in non-system-exiting exceptions and user-defined exceptions
ArithmeticError
is the base exception class for arithmetic errors such asFloatingPointError
,ZeroDivisionError
, andOverflowError
.FloatingPointError
– you can catch this exception when the operation of a floating-point value fails. However, the exception is always defined and it can only be raised if theWANT_SIGFPE_HANDLER
symbol is defined in the pyconfig.h file.ZeroDivisionError
happens when second argument of the division or modulo operation equals zero
LookupError
defines a base class forIndexError
andKeyError
exceptions that raised by Python when developer is trying to manipulate non-existing or is invalidindex
orkey
values at sequence or mapping.IndexError
exception happens when a referenced sequence is out of rangeKeyError
you can catch this exception if a mapping key not found in the set of existing keysOverflowError
– this exception happens when the results from an arithmetic operation are out of range and also if integers are out of a required range
Concrete exceptions in Python
Concrete exceptions in Python are build-in exceptions that inherited directly from the Exception
class.
Here’s a quick description of all concrete exceptions:
BufferError
– Python throws this exception when a buffer-related operation fails to execute correctlyAssertionError
is raised when anassert
statement fails in Python codeValueError
– you can catch this exception when a built-in function or operation receives the correct type of argument but with an invalid valueUnicodeError
– This is a subclass ofValueError
and is raised when aUnicode
decoding or encoding error is captured.
TypeError
– Python throws this exception when developer apply an inappropriate type object to a function or an operation. Astring
that gives the details related to the mismatch is returned by this exception.SystemError
– Python throws this exception when the interpreter encounters an internal error.StopIteration
– The built-in functionnext()
and the iterator’s__next__()
method raise this exception to indicate that all items are produced by the iterator.RuntimeError
– raises when no other exception applies. Astring
is returned with the details of the actual problem encountered during execution.RecursionError
– Derived from theRuntimeError
and is raised when the maximum recursion depth has been exceeded.NotImplementedError
– The exception is derived from theRuntimeError
and is raised when derived classes override the abstract methods in user-defined classes.
SyntaxError
– you can catch this exception when an interpreter encounters wrong syntax. A syntax error can be experienced in an import statement or when reading a standard input or when calling the builtin functioneval()
orexec()
.
ReferenceError
– Python throws this exception when a weak reference proxy to accesses an attribute of the reference after the garbage collection.AttributeError
– you’re getting this exception whenever the assignment or reference of an attribute fails. This can happen because the referred attribute does not exist.MemoryError
– when Python runs out of memory it throws this exceptionEOFError
– TheEOFError
is raised if the built-in functions such asinput()
encounters an end-of-file (EOF) condition without reading any data. For instance, in case thereadline()
builtin function encounters an EOF, it returns an empty string.ImportError
– Raised when theimport
statement fails to load a module or when the from list in from import has a name that does not exist.ModuleNotFoundError
– It is a subclass of theImportError
and is raised when a module could not be found. In addition to that, if None is found insys.modules
the exception can also be raised.
NameError
– The exception is raised when aglobal
orlocal name
is not found.UnboundLocalError
– This exception is raised when a reference is made to a local variable in a method or a function but there is no value bound to that variable.
OSError([arg])
– Whenever a system function returns a system-related error such as I/O failures including “disk full” or “file not found” errors.FileNotFoundError
– Raised when a requested file directory or file does not exist.FileExistsError
– This exception is raised when attempting to create an already existing file or a directory.TimeoutError
– Raised when a system function timed out at the system level.PermissionError
– Raised when attempting to run an application without the required access rights.ConnectionError
– This is the base class for connection related issues and the subclasses are:BrokenPipeError
– Raised when attempting to write on a pipe closed on the other end. Also when attempting to write on a shut down socket.ConnectionResetError
– The exception is raised when a peer resets a connection.ConnectionAbortedError
– Raised when a peer aborts a connection attempt.ConnectionRefusedError
– Raised if a peer refuses a connection attempt.
ProcessLookupError
– It gets raised in case a specified process does not exist.InterruptedError
– The exception is raised when a system class is interrupted by an incoming signal. In Python 3.5+, Python retries system calls whenever a system call is interrupted.IsADirectoryError
– It is raised when a file operation such asos.remove()
is requested on a directory.NotADirectoryError
– Raised when a directory operation such asos.listdir()
is requested on an argument that is not a directory.ChildProcessError
– Gets raised when a child process operatio fails.BlockingIOError
– This error is raised when an operation would block on an object set for non-blocking operation.
Warnings in Python
Developers typically use warning messages when they need to alert the user about some important condition in a program. Usually, such a condition doesn’t raise an exception or terminate the program. A good example might be to print a warning when a program uses an obsolete Python module.
Here’s a list of built-in Python warnings:
FutureWarning
– This is the base class of warnings about deprecated features.BytesWarning
– Base class for warning related to bytearray and bytes.SyntaxWarning
– For dubious syntax, this is the base class of such warnings.ImportWarning
– Base class for warning related to probable mistakes in module imports.Warning
– Base class for warning categories.UserWarning
– This is the base class forwarnings
that have been generated by the user code.ResourceWarning
– Base class for warnings associated with resource usage.PendingDeprecationWarning
– This is the base class forwarnings
related to obsolete features that are expected to be deprecated in the future. For already active deprecation theDeprecationWarning
is used.DeprecationWarning
– Base class for the warning associated with deprecated features.UnicodeWarning
– Base class for warning related to Unicode.
User-defined exceptions in Python
You can inherit from any built-in exception class to create your own exception type.
User-defined exceptions allow us to display more relevant and detailed information when an exception occurs during program execution, for example:
class CustomError(Exception):
pass
raise CustomError('My custom error')
Here’s the program output:
Traceback (most recent call last):
File "multiple_except.py", line 4, in <module>
raise CustomError('My custom error')
__main__.CustomError: My custom error
Customizing exception classes in Python
If you’d like to implement more meaningful exception messages in your Python program, you can do it by implementing an exception class constructor:
ALLOWED_CAR_COLOURS = ['black', 'red', 'green']
class IncorrectCarColourException(Exception):
"""Exception raised for errors in the car colour input.
Attributes:
colour -- car colour
"""
def __init__(self, colour):
self.colour = colour
self.message = f'''
{self.colour} car colour is not allowed.
Allowed values are {ALLOWED_CAR_COLOURS}
'''
super().__init__(self.message)
car_color = input("Enter car colour: ")
if not car_color in ALLOWED_CAR_COLOURS:
raise IncorrectCarColourException(car_color)
Here’s an execution example:
Enter car colour: white
Traceback (most recent call last):
File "multiple_except.py", line 22, in <module>
raise IncorrectCarColourException(car_color)
__main__.IncorrectCarColourException:
white car colour is not allowed.
Allowed values are ['black', 'red', 'green']
Summary
We have seen different types of exceptions, both built-in and user-defined ones. In addition to that, we have reviewed specific exceptions and errors that occur to raise these exceptions. The article has a detailed explanation of how to handle and raise exceptions in a Python program.
Introduction to Python KeyboardInterrupt
As we already know what the exceptions are and how to handle them in Python. In layman language, exceptions are something that interrupts the normal flow of the program. Similarly KeyboardInterrupt is a python exception which is generated when the user/programmer interrupts the normal execution of a program. Interpreter in python checks regularly for any interrupts while executing the program. In python, interpreter throws KeyboardInterrupt exception when the user/programmer presses ctrl – c or del key either accidentally or intentionally. KeyboardInterrupt exception inherits the BaseException and similar to the general exceptions in python, it is handled by try except statement in order to stop abrupt exiting of program by interpreter.
Syntax:
As seen above, KeyboardInterrupt exception is a normal exception which is thrown to handle the keyboard related issues. There is no such specific syntax of KeyboardInterrupt exception in Python, it is handled in the normal try and except block inside the code. Code which can cause the error is placed inside the try block with the ‘raise’ keyword to raise that exception or the python interpreter automatically raises it. To catch the exception and perform desired tasks, special code inside the except block is written.
try:
# code that can raise the exception
# raising this exception is not mandatory
raise KeyboardInterrupt
except KeyboardInterrupt:
# code to perform any specific tasks to catch that exception
How does KeyboardInterrupt Exception work in Python?
One of the most annoying things while working with python is that it exits the program once the user presses ctrl – c either intentionally or mistakenly which is a big problem when the bulk data is getting processed like retrieving records from database, handling, executing a big program handling many tasks at a time, etc. This exception works in a very simple manner like other exceptions in Python. Only thing about this exception is that it is user generated and there is no involvement of the computer in raising it. In order to understand the working of KeyboardInterrupt exception in Python, lets understand the below written code first.
Code:
try:
# code inside the try block which can cause an exception
# taking the input ‘name’ from the user
name = input('Enter the name of the user ')
# writing the different exception class to catch/ handle the exception
except EOFError:
print('Hello user it is EOF exception, please enter something and run me again')
except KeyboardInterrupt:
print('Hello user you have pressed ctrl-c button.')
# If both the above exception class does not match, else part will get executed
else:
print('Hello user there is some format error')
In the above code:
- First the code inside the try block is executed.
- If the user presses the ctrl – c, an exception will be raised, execution of the rest of the statements of the try block is stopped and will move the except block of the raised exception.
- If no exceptions arise in the try block, then the execution continues in a normal manner but no ‘except’ block statements are executed.
- If the exception is raised but does not match with the class name of the exception handler present after the except keyword, it will start looking for the respective catch block to handle it outside the inner try block. If not found, then it will exit the program with the normal python message.
How to Avoid KeyboardInterrupt Exceptions in Python?
- There is no such way to avoid the KeyboardInterrupt exception in Python as it will automatically raise the KeyboardInterrupt exception when the user presses the ctrl – c. There are few things that we can do in order to avoid this.
- As we all know that finally block is always executed. So if the exception is raised and we are tangled in some infinite loop then we can write a clean code in the finally block (which will get executed in every case) which can help us to backtrack the situation.
- It totally depends on the programmer how he/she codes in order to avoid this situation as every programmer has a different way of thinking and hence coding.
- Some add a flag or variable which gets incremented when the user clicks on the ctrl – c button or some programmers creates a separate function which takes some extra input or keeps track of the user pressing ctrl- c keys and responds accordingly.
Example of Python KeyboardInterrupt
Given below is the example mentioned :
General output when the user presses the ctrl – c button.
Code:
try:
# code inside the try block which can cause an exception
# taking the input ‘name’ from the user
name = input('Enter the name of the user ')
# writing the different exception class to catch/ handle the exception
except EOFError:
print('Hello user it is EOF exception, please enter something and run me again')
except KeyboardInterrupt:
print('Hello user you have pressed ctrl-c button.')
# If both the above exception class does not match, else part will get executed
else:
print('Hello user there is some format error')
Output 1:
When the user presses the ctrl -c button on asking the username by the program, the below output is generated.
Explanation:
In the above output, the print statement written for the KeyboardInterrupt exception is displayed as the user presses the ctrl – c which is a user interrupt exception.
Output 2:
When the user presses the ctrl – d button on asking the username by the program, below given output is generated.
Explanation:
In the above output, a print statement written under the EOF exception class is displayed as the user presses the ctrl – d button which indicates the end of file. This indicates that the desired exception class is searched when the exception arises if catched in the code, the following block is executed.
Conclusion
Above article clearly explains what the KeyboardInterrupt exception is, how it is raised and is handled in Python. KeyboardInterrupt exception as the name indicates is a simple exception which is raised when the program is interrupted by the user keyboard. For any programmer be it a newbie or an expert it is very important to understand each and every type of exception in detail in order to deal with them accordingly and write a program efficiently (able to handle any kind of such situations).
Recommended Articles
This is a guide to Python KeyboardInterrupt. Here we discuss how does KeyboardInterrupt exception work, how to avoid KeyboardInterrupt exceptions in Python with respective examples. You may also have a look at the following articles to learn more –
- Lambda in Python
- Python Iterator Dictionary
- Python BeautifulSoup
- Quick Sort in Python