## ++Тема 7++<br>Ошибки и исключения. Обработка исключений (c) Яценко Р.Н., 2019-2022 [Учебный центр компьютерных технологий "Кит"](http://kit.kh.ua/) <img src="https://i.imgur.com/Kh901c1.png" style="width: 150px; position: fixed; top: 10px; right: 10px; border: 0; box-shadow: none; z-index: -1000;"> --- ## 1. Ошибки и исключения ---- ### Синтаксические ошибки - **Синтаксические ошибки** нарушают синтаксис и пунктуацию языка. Интерпретатор Python, встретив ошибочное выражение, не знает как его интерпретировать. - Останавливается выполнение программы и выводится соответствующее сообщение с указанием на место ошибки: ``` >>> 1a = 10 File "<stdin>", line 1 1a = 10 ^ SyntaxError: invalid syntax ``` ---- ### Исключение SyntaxError - В терминологии языка Python возникло исключение, принадлежащее классу `SyntaxError` - Согласно документации Python *синтаксические ошибки* относят к ошибкам, а все остальные (*семантические ошибки*) – к исключениям ---- ### Исключение NameError Если вы попытаетесь обратиться к переменной, которой не было присвоено значение, что в случае Python означает, что переменная вообще не была объявлена, она не существует, то возникнет исключение `NameError`: ``` >>> a = 0 >>> print(a + b) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'b' is not defined ``` ---- ### Исключение ValueError В примере строку `"Hi"` нельзя преобразовать к целому числу. Возникает исключение `ValueError`, потому что функция `int()` не может преобразовать такое значение: ``` >>> int("Hi") Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: invalid literal for int() with base 10: 'Hi' ``` ---- ### Исключение TypeError Число `8` и строка `"3"` принадлежат разным типам, операция сложения между которыми не поддерживается. При попытке их сложить возникает исключение `TypeError`: ``` >>> 8 + "3" Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unsupported operand type(s) for +: 'int' and 'str' ``` ---- ### Исключение ZeroDivisionError Деление на ноль вызывает исключение `ZeroDivisionError`: ``` >>> 1/0 Traceback (most recent call last): File "<stdin>", line 1, in <module> ZeroDivisionError: division by zero ``` ---- ### Другие типы исключений Тип исключения | Описание -|----- `IOError` | Генерируется, если невозможно выполнить операцию ввода/вывода `IndexError` | Генерируется, если в последовательности не найден элемент с указанным индексом `КeyError` | Генерируется, если в словаре не найден указанный ключ --- ## 2. Обработка исключений ---- ### Перехват исключений - Нередко действия пользователя приводят к тому, что в программе возникает исключение. Например, программа ожидает ввод числа, но человек ввел букву. Попытка преобразовать ее к числу приведет к возбуждению исключения `ValueError` - На этот случай в Python существует специальный оператор, позволяющий перехватывать возникающие исключения и обрабатывать их ---- ### Оператор try-except - В Python перехват исключений выполняет оператор `try-except`. "Try" переводится как "попытаться", "except" -- как исключение - Словами описать его работу можно так: "Попытаться сделать то-то и то-то, если при этом возникло исключение, то сделать вот это и это": ``` python try: # блок инструкций, где может возникнуть исключение except: # блок обработки исключения ``` ---- ### Пример ``` python= n = input("Введите целое число: ") try: n = int(n) print("Удачно") except: print("Что-то пошло не так") ``` ---- ### Ветка except **Если в теле try исключения не возникает, то тело ветки except не выполняется** - Вот пример вывода программы, когда пользователь вводит целое число: ``` Введите целое число: 100 Удачно ``` - А здесь – когда вводит не то, что ожидалось: ``` Введите целое число: AA Что-то пошло не так ``` ---- ### Перехват определенных исключений В теле `try` могут возникать разные исключения, и у каждого из них должен быть свой обработчик. Поэтому более правильным является указание типа исключения после ключевого слова `except`: ``` python= try: n = input('Введите целое число: ') n = int(n) print("Все нормально. Вы ввели число", n) except ValueError: print("Вы ввели не целое число") ``` ---- ### Множественный перехват исключений Если в теле `try` возникнет еще какое-нибудь исключение, то оно не будет обработано. Для него надо написать отдельную ветку `except`: ``` python= try: a = float(input("Введите делимое: ")) b = float(input("Введите делитель: ")) c = a / b print("Частное: %.2f" % c) except ValueError: print("Нельзя вводить строки") except ZeroDivisionError: print("Нельзя делить на ноль") ``` ---- ### Группировка исключений Несколько исключений можно сгруппировать в одну ветку и обработать совместно: ``` python= try: a = float(input("Введите делимое: ")) b = float(input("Введите делитель: ")) c = a / b print("Частное: %.2f" % c) except ValueError, TypeError: print("Нельзя вводить строки") except ZeroDivisionError: print("Нельзя делить на ноль") ``` ---- ### Ветки else и finally - Блок **`else` сработает, если исключений в `try` не было**, т. е. не было переходов на блоки `except` - Блок **`finally` выполняется всегда**, независимо от того, выполнялись ли блоки `except` или нет ``` python= try: n = input('Введите целое число: ') n = int(n) except ValueError: print("Вы что-то попутали с вводом") else: # выполняется, когда в блоке try не возникло исключения print("Все нормально. Вы ввели число", n) finally: # выполняется в любом случае print("Конец программы") ``` ---- ### Примеры выполнения ``` Введите целое число: 4.3 Вы что-то попутали с вводом Конец программы Введите целое число: 4 Все нормально. Вы ввели число 4 Конец программы ``` --- ## 3. Вложенная обработка ---- ### Обработчики для обработчиков Исключение может возникнуть в блоке `except`, `else` или `finally`, и тогда им нужен собственный обработчик. Модифицируем немного предыдущую программу и специально сгенерируем исключение в теле `except`: ``` python= try: n = input('Введите целое число: ') n = int(n) except ValueError: print("Вы что-то попутали с вводом") 3 / 0 except ZeroDivisionError: print("Деление на ноль") else: print("Все нормально. Вы ввели число", n) finally: print("Конец программы") ``` ---- ### Выполнение ``` Введите целое число: а Вы что-то попутали с вводом Конец программы Traceback (most recent call last): File "test.py", line 15, in <module> n = int(n) ValueError: invalid literal for int() with base 10: 'а' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "test.py", line 18, in <module> 3 / 0 ZeroDivisionError: division by zero ``` Мало того, что не было обработано деление на ноль, само исключение `ValueError` посчиталось необработанным ---- ### Решение проблемы ``` python=4 except ValueError: print("Вы что-то попутали с вводом") try: 3 / 0 except ZeroDivisionError: print("Деление на ноль") ``` --- ## 4. Полный синтаксис try ---- ### try-except-else-finally ``` python= try: # Здесь располагается код, который может вызвать исключение [raise Exception("message")] # Инструкция raise возбуждает исключение # Exception, это один из стандартных типов исключения, может # использоваться любой другой, в том числе пользовательский except (Тип исключения1, Тип исключения2, ...) [as Переменная]: # Код в блоке выполняется, если тип исключения совпадает # с одним из типов (Тип исключения1, Тип исключения2, ...) # или является наследником одного из этих типов. # Полученное исключение доступно в необязательной Переменной. ``` ---- ``` python=12 [except (Тип исключения3, Тип исключения4, ...):] # Количество блоков except не ограничено [raise] # Сгенерировать исключение "поверх" полученного; # без параметров - повторно сгенерировать полученное [except:] # Будет выполнено при любом исключении, # не обработанном типизированными блоками except [else:] # Выполняется код блока, если не было перехвачено исключений. [finally:] # Будет исполнено в любом случае, после соответствующего # блока except или else ``` ---- ### Пример со списком ``` python= from random import randint, seed seed() L = [] for j in range(20): L.append(randint(10, 99)) print(L[j], end=' ') print() while True: N = int(input('Введите значение элемента ' 'для удаления или 0 для выхода\nN = ')) if not N: print('Вы вышли из программы') break ``` ---- ``` python=16 try: x = L.index(N) except ValueError: print('Такого элемента в массиве не существует!') else: L.remove(N) print('Элемент в позиции', x, 'успешно удален!') finally: for it in L: print(it, end=' ') print() ``` ---- ``` 50 58 13 41 53 65 27 29 73 52 31 13 64 18 97 42 95 24 37 60 Введите значение элемента для удаления или 0 для выхода N = 43 Такого элемента в массиве не существует! 50 58 13 41 53 65 27 29 73 52 31 13 64 18 97 42 95 24 37 60 Введите значение элемента для удаления или 0 для выхода N = 65 Элемент в позиции 5 успешно удален! 50 58 13 41 53 27 29 73 52 31 13 64 18 97 42 95 24 37 60 Введите значение элемента для удаления или 0 для выхода N = 0 Вы вышли из программы ``` --- ## 5. Оператор assert <!-- https://pythonist.ru/assert-v-python/ --> ---- ### Назначение - Оператор `assert` -- это оператор Python, используемый для отладки кода - Работает как логическое выражение, проверяя, является ли заданное условие истинным или ложным: - Если истинно, то ничего не происходит и выполняется следующая строка кода - Если ложно, оператор assert останавливает выполнение программы и выдает ошибку `AssertionError` ---- ### Синтаксис - Синтаксис использования оператора `assert` следующий: ```python assert <condition> ``` - Можно добавить дополнительное сообщение, которое будет выводиться, если условие ложно: ```python assert <condition>, <message> ``` ---- ### Пример ```python= num1 = 10 num2 = int(input()) assert num2 != 0, "Делитель равен нулю" print("Результат:", num1/num2) ``` ``` 0 Traceback (most recent call last): File "main.py", line 3, in <module> AssertionError: Делитель равен нулю 2 Результат: 5.0 ``` --- ## Домашнее задание Набрать и запустить на выполнение все примеры программ из лекции ![](https://i.imgur.com/gKDsna4.png) (c) Яценко Р.Н., [УЦКТ "Кит"](http://kit.kh.ua/), 2019-2022
{"metaMigratedAt":"2023-06-16T22:51:26.219Z","metaMigratedFrom":"YAML","title":"Тема 7. Ошибки и исключения. Обработка исключений","breaks":false,"slideOptions":"{\"allottedMinutes\":80,\"transition\":\"slide\",\"theme\":\"beige\",\"slideNumber\":\"c\",\"spotlight\":{\"enabled\":true}}","contributors":"[{\"id\":\"93a8c43f-1b5b-4461-9101-89b183ccbc1c\",\"add\":11243,\"del\":351}]"}
    276 views