Искать
Вы превысили запрос на
0 знаков

37. Обработка исключений (try/except) в Python

Не пройден
0
0

Кратко

- В Python обработка исключений необходима для предотвращения остановки программы при возникновении ошибок.

- Исключения в Python подразделяются на группы: BaseException, Exception, ArithmeticError, AssertionError, AttributeError, BufferError, EOFError, ImportError, LookupError, OSError, RuntimeError, StopIteration, SyntaxError, SystemError, TypeError, ValueError, Warning.

- Конструкция try/except в Python позволяет "отлавливать" исключения и выполнять код в зависимости от типа исключения.

- Ключевое слово as в Python помогает узнать, какое исключение было поднято.

- Ключевое слово raise используется для генерации исключений.

- Утверждение assert в Python используется для проверки истинности утверждений и возбуждения исключения AssertionError при ложном результате.

Введение

В предыдущем уроке вы познакомились с циклами while/else и for/else. В этом уроке разберем, как обрабатывать исключения, вызываемые интерпретатором Python. Уверен, вы писали код, который отлично работал, но при вводе определенных данных, например, строки вместо числа, программа останавливалась и выдавала ошибку. Это генерировалось исключение и, так как вы его не обрабатывали, работа программы прекращалась.

Давайте целенаправленно вызовем исключение ZeroDivisionError. Если вы разделите любое число на ноль, то получите подобную ошибку:

Пример (python)
Traceback (most recent call last):
  File "C:/test.py", line 1, in <module>
    print(5/0) 
ZeroDivisionError: division by zero 

Этим сообщением интерпретатор Python нам говорит об ошибке в первой строке файла test.py, а точнее, в выражении print(5/0). В последней строке ошибки содержится название исключения и ее краткое описание.

Иерархия исключений в Python

Теперь кратко рассмотрим некоторые из исключений, которые могут возникнуть в языке Python. Сразу оговорюсь, нет необходимости запоминать все эти исключения, так как всегда их можно посмотреть в справочнике или здесь. С другой стороны, знание возможных ошибок поможет их предвидеть и не допустить. Материал этого раздела находится под спойлером, так как получился объемным.

BaseException – это базовое исключение, от него берут начало все остальные исключения.

В базовое исключение входят:

  • GeneratorExit: будет вызвано в случае применения метода close, объекта generator.
  • SystemExit: будет вызвано функцией sys.exit в случае выхода из программы.
  • KeyboardInterrupt: будет вызвано, если пользователь нажал сочетание клавиш Ctrl + C в консоли.
  • Exception: в отличие от предыдущих, это группа не системных исключений, а «пользовательских», если так можно выразиться.

Исключения Exception

Группа исключений Exception подразделяется на следующие:

Группа исключений ArithmeticError

Исключения, связанные с арифметическими ошибками. Исключение FloatingPointError связано с выполнением неудачной операции с плавающей точкой. Исключение OverflowError возникает, когда результат арифметической операции слишком большой и не может быть представлен. Исключение ZeroDivisionError возникает из-за деления на ноль. Для примера, следующий код не будет работать, так как будет вызвано исключение OverflowError:

Пример (python)
pi = 0
for k in range(350):
    pi += 16.**k
print(pi)   

Исключение AssertionError

Вызывается, если результат проверки инструкции assert является ложным. Например:

Пример (python)
assert 1 == 0   

К инструкции assert мы еще вернемся.

Исключение AttributeError

Возникает, если у объекта нет такого атрибута или в случае ошибки доступа к нему. Например:

Пример (python)
a = 10
a.atr  

Так как переменная (объект) a не имеет атрибута atr, то будет вызвано исключение:

Пример (python)
Traceback (most recent call last):
  File "C:/test.py", line 2, in <module>
    a.atr()
AttributeError: 'int' object has no attribute 'atr' 

Исключение BufferError

Возникает, когда операция с буфером не может быть выполнена по тем или иным причинам. Например, буфер не доступен для записи, так как работает только в режиме «для чтения».

Исключение EOFError

Возникает, когда программа обнаруживает конец файла, то есть маркер EOF в процессе считывания данных.

Исключение ImportError

Возникает, если вы попробуете подключить несуществующий модуль при помощи инструкции import или отсутствующий атрибут.

Группа исключений LookupError

Исключение IndexError вызывается, если используемый индекс выходит за диапазон, например, обратимся к четвертому списка из трех элементов:

Пример (python)
a = [1, 2, 3]
a[3]  

Исключение KeyError возникает, если вы обратились к несуществующему ключу:

Пример (python)
a = {'1': 1, '2': 2, '3': 3}
a['4'] 

Исключение MemoryError

Возникает, если закончилась память при выполнении операции.

Исключение NameError

Возникает, если не найдено имя переменной, функции или другого объекта, например:

Пример (python)
print(a)  

Результат:

Пример (python)
Traceback (most recent call last):
  File "C:/test.py", line 1, in <module>
    print(a)
NameError: name 'a' is not defined  

Группа исключений OSError

Большая по своему составу группа исключений, связанных с системой.

В нее входит исключение BlockingIOError, которое поднимается, когда блокируется ввод/вывод. Исключение ChildProcessError возникает при неудачной операции с дочерним процессом. Исключение ConnectionError является еще одной группой, связанной с проблемами подключения. Исключение FileExistsError будет поднято, если вы попытаетесь создать уже существующий файл или директорию. Исключение FileNotFoundError возникнет, если вы обратитесь к несуществующему файлу или директории. Если системный вызов был прерван каким-либо входящим сигналом, то поднимется исключение InterruptedError. Исключение IsADirectoryError возникнет, если интерпретатор Python ожидал файл, но это оказалась директория. Исключение NotADirectoryError является противоположным предыдущему. Если возникли проблемы с правами доступа, то поднимется исключение PermissionError. Исключение ProcessLookupError возникнет, если такого процесса не существует, а TimeoutError, если закончилось время ожидания.

Исключение ReferenceError

Исключение ReferenceError поднимается в случае обращения к атрибуту объекта с помощью слабой ссылки. Тема про слабые ссылки не такая простая, но, возможно, мы к ней вернемся. Если кратко: слабые ссылки нужны для организации хэш-таблиц из «увесистых» объектов. За работу слабых ссылок отвечает модуль weakref.

Исключение RuntimeError

Такое исключение возникает в связи с ошибкой времени исполнения не попадающей под другие категории. До версии Python 3.5. под это исключение попадала бесконечная рекурсия, однако сейчас под это выделен новый тип исключений: RecursionError.

Исключение StopIteration

Поднимается функцией next, если в итераторе закончились элементы. Про итераторы мы поговорим в последующих уроках.

Исключение SyntaxError

Наверное, с исключением SyntaxError вы будете встречаться чаще всего. Оно поднимается парсером в случае нахождения синтаксических ошибок в исходном коде.

Исключение SystemError

Поднимается, когда возникают внутренние ошибки на уровне интерпретатора.

Исключение TypeError

Исключение TypeError поднимается при попытке обработки объекта, для которого такие действия неприменимы. Например, сложение строки и числа:

Пример (python)
print('Hello' + 20)   

Если вы забыли, что язык Python является сильно типизированным, то вернитесь к уроку про типы данных.

Исключение ValueError

Возникает, когда в функцию передан неправильный аргумент, т.е. тип переданного аргумента правильный, а значение не поддерживается.

Группа исключений Warning

Исключения группы Warning связаны с различными категориями предупреждений.

Конструкция try/except в Python

Настало время перейти к конструкции, которая позволяет «отлавливать» исключения в Python. Предположим, у нас есть программа, на вход которой поступает два числа, после чего одно делится на другое.

Пример (python)
a, b = int(input()), int(input())
print(a / b) 

Вы уже знаете, что при определенных входных данных, программа завершится. Конечно, от деления на ноль можно защититься при помощи условной конструкции if:

Пример (python)
a, b = int(input()), int(input())
if (b != 0):
    print(a / b)
else:
    print("b равно 0") 

Перепишем этот пример с использованием инструкции try/except:

Пример (python)
try:
    a, b = int(input()), int(input())
    print(a / b)
except ZeroDivisionError:
    print("b равно 0")  

Как же работает инструкция try/except? Сначала будет выполнено выражение, которое расположено в блоке try. Если внутри блока try не возникло никаких исключений, то блок except пропускается и выполняется дальнейший код.

Если все же внутри блока try возникло исключение, то оставшийся код в этом блоке пропускается и выполняется код в блоке except и управление передается следующей инструкции после этого блока. Например, следующая программа завершится корректно, даже при делении на ноль:

Пример (python)
try:
    a, b = int(input()), int(input())
    print(a / b)
except ZeroDivisionError:
    print("b равно 0")
print("Конец программы") 

Однако если в блоке try поднялось исключение, тип которого не указан в блоке except, программа прервется и будет выдана ошибка. Блоков except может быть несколько:

Пример (python)
try:
    a, b = int(input()), int(input())
    print(a / b)
except ZeroDivisionError:
    print("b равно 0")
except ValueError:
    print("Введите число") 

Исключение ValueError возникнет, если вы введете, например, строку вместо числа. Если необходимо выполнить одни и те же действия при разных типах исключений, то можно их объединить в одном блоке except.

Пример (python)
try:
    a, b = int(input()), int(input())
    print(a / b)
except (ZeroDivisionError, ValueError):
    print("Ошибка в работе программы.") 

Конструкция try/except поддерживает возможность перехватывать все исключения, для этого можно не указывать тип:

Пример (python)
try:
    a, b = int(input()), int(input())
    print(a / b)
except:
    print("Ошибка в работе программы.") 

Конструкция try/except в Python имеет еще два опционных блока: finally и else. Блок finally выполняется всегда, независимо от того, было исключение или нет. Снова может показаться, что это бесполезный блок, ведь если except будет ловить все ошибки, то последующий код будет без проблем выполняться. Приведу пример, когда блок finally действительно необходим:

Пример (python)
import sys

try:
    while True:
        pass
except KeyboardInterrupt:
    print('Ctrl + C')
    sys.exit()
finally:
    print("Выполнение чего-то важного")
print("Конец программы") 

Программа будет закрыта только при помощи сочетания клавиш Ctrl + C. Запустите пример и убедитесь что последний print() будет пропущен. А что если перед закрытием программы при помощи сочетания клавиш Ctrl + C необходимо сохранить пользовательскую информацию? Блок finally в данном случае вас выручит.

Опционный блок else в конструкции try/except нужен, чтобы выполнить необходимые инструкции только в том случае, если исключения не вызывались. Далее пример:

Пример (python)
try:
    a, b = int(input()), int(input())
    print(a / b)
except:
    print("Ошибка в работе программы.")
else:
    print("Конец программы")  

Ключевое слово as в Python

Ключевое слово as в контексте исключений может помочь узнать, какое именно исключение было поднято.

Пример (python)
try:
    a, b = int(input()), int(input())
    print(a / b)
except Exception as e:
    print(f"Исключение: {type(e)}")
    print(f"Что случилось: {e}")  

В этом примере мы используем f-строки и функцию type(). Если про них забыли, то вернитесь к этим урокам чтобы освежить в памяти. К ключевому слову as мы еще вернемся, когда будем работать с файлами.

Ключевое слово raise в Python

Иногда необходимо сгенерировать исключение, можно использовать ключевое слово raise:

Пример (python)
try:
    a, b = int(input()), int(input())
    if (b == 0):
        raise ZeroDivisionError
    print(a / b)

except ZeroDivisionError:
    print("Деление на ноль")  

Или вы можете вызвать свое исключение в виде текстового сообщения:

Пример (python)
try:
    a, b = int(input()), int(input())
    if (b == 0):
        raise ValueError("Деление на ноль")
    print(a / b)

except Exception as e:
    print(e)   

Утверждение assert в Python

Утверждение assert в Python используется в отладочных целях, а именно, для проверки истинности утверждений. Если результат проверки будет ложным, то будет возбуждено исключение AssertionError.

Инструкцию assert рекомендуется использовать для проверки ситуаций, которые не должны происходить, то есть те, которые нельзя обработать.

Заключение

В процессе программирования ошибок не избежать. Ошибки могут появиться как из-за неправильного ввода данных пользователем, так и по многим другим причинам, включая невнимательность программиста.

В этом уроке мы научились обрабатывать ошибки в Python при помощи конструкций try/excepttry/except/else и try/except/finally. Узнали, как возбудить свою ошибку при помощи ключевого слова raise. Кратко узнали о ключевом слове as и утверждении assert.

Перед обработкой исключений, оцените как проще и эффективней предупредить ошибку: использовать try/except или обычную условную конструкцию if. Далее подведем итоги раздела «Снова циклы и немного исключений» и начнем работать с файлами.

Тест

Две секундочки...

Похожие уроки Codebra

@codebra_official
Подписывайся на наш Telegram-канал!
Новости, полезный материал,
программирование и ИБ
Первое знакомство с PythonЗнакомство с Python
Поиск хостов с помощью NmapРазведка и сканирование
Работа с файлами в PythonЗнакомство с Python
Типы данных в PythonЗнакомство с Python
Генераторы и оператор yield в PythonЗнакомство с Python
Написание модулей в PythonЗнакомство с Python
Еще о возможностях модулей в PythonЗнакомство с Python
Пользовательские функции в PHPКурс по PHP
Погружение в PythonЗнакомство с Python
Впервые на сайте Codebra?

Извините за это всплывающее окно, меня они тоже раздражают.

Образовательный ресурс codebra.ru полностью посвящен программированию и компьютерной безопасности. Все курсы и уроки находятся на главной странице. Ради интереса можете посмотреть на содержимое курсов по Пентесту Active Directory, Python, HTML и CSS, JavaScript, C++ и другие, размещенные на главной странице.

Если что-то не нашли, то воспользуйтесь поиском по сайту, который находится на главной странице в самом верху.

Удачи в обучении!

Закрыть окно