Винятки в Python. Конструкція try … except для оброобки винятків#
Винятки (exceptions) — ще один тип даних в Python. Винятки необхідні для того, щоб повідомляти програмісту про помилки. Найпростіший приклад винятку — поділ на нуль:
100/0
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_22196/621970991.py in <module>
----> 1 100/0
ZeroDivisionError: division by zero
У цьому прикладі інтерпретатор повідомляє про те, що він впіймав виняток і надрукував інформацію (Traceback (most recent call last)).
Далі ім’я файлу (~\AppData\Local\Temp/ipykernel_22196/621970991.py in <module>). Ім’я дивне, тому що програма виконується в інтерактивному режимі, рядок в файлі (line 1);
Вираз, в якому сталася помилка (100/0). Назва винятку (ZeroDivisionError) і короткий опис винятку (division by zero).
Зрозуміло, можливі й інші винятки:
2+'1'
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_22196/3484758724.py in <module>
----> 1 2+'1'
TypeError: unsupported operand type(s) for +: 'int' and 'str'
int('qwerty')
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_22196/937401132.py in <module>
----> 1 int('qwerty')
ValueError: invalid literal for int() with base 10: 'qwerty'
У цих двох прикладах генеруються винятки TypeError і ValueError відповідно. Підказки дають повну інформацію про те, де породжений виняток, і з чим це пов’язано.
Ієрархія вбудованих в Python винятків#
BaseException — базовий виняток, від якого беруть початок всі інші.
SystemExit — виняток, що породжується функцією sys.exit при виході з програми.
KeyboardInterrupt — породжується при перериванні програми користувачем (зазвичай сполучення клавіш Ctrl+C).
GeneratorExit — породжується при виклику методу close об’єкту generator.
Exception — а ось тут вже закінчуються повністю системні виключення (які краще не чіпати) і починаються звичайні, з якими можна працювати.
StopIteration — породжується вбудованою функцією next, якщо в ітераторі більше немає елементів.
ArithmeticError — арифметична помилка.
FloatingPointError— породжується при невдалому виконанні операції з плаваючою комою. На практиці зустрічається нечасто.OverflowError— виникає, коли результат арифметичної операції занадто великий для представлення. Не з’являється при звичайній роботі з цілими числами (так як Python підтримує довгі числа), але може виникати в деяких інших.ZeroDivisionError— ділення на нуль.
AssertionError — вираз у функції assert помилковий.
AttributeError — об’єкт не має даного атрибута (значення або методу).
BufferError — операція, пов’язана з буфером, не може бути виконана.
EOFError — функція натрапила на кінець файлу і не змогла прочитати те, що хотіла.
ImportError — не вдалося імпортування модуля або його атрибута.
LookupError — некоректний індекс або ключ.
IndexError — індекс не входить в діапазон елементів.
KeyError — неіснуючий ключ (в словнику, множині або іншому об’єкті).
MemoryError — недостатньо пам’яті.
NameError — не знайдено змінної з таким ім’ям.
UnboundLocalError — зроблено посилання на локальну змінну у функції, але змінна не визначена раніше.
OSError — помилка, пов’язана з системою.
BlockingIOError
ChildProcessError — невдача при операції з дочірнім процесом.
ConnectionError — базовий клас для винятків, пов’язаних з підключеннями.
BrokenPipeErrorConnectionAbortedErrorConnectionRefusedErrorConnectionResetError
FileExistsError — спроба створення файлу або директорії, яка вже існує.
FileNotFoundError — файл або директорія не існує.
InterruptedError — системний виклик перерваний вхідним сигналом.
IsADirectoryError — очікувався файл, але це директорія.
NotADirectoryError — очікувалася директорія, але це файл.
PermissionError — не вистачає прав доступу.
ProcessLookupError — вказаного процесу не існує.
TimeoutError — закінчився час очікування.
ReferenceError — спроба доступу до атрибуту зі слабким посиланням.
RuntimeError — виникає, коли виняток не попадає ні під одну з інших категорій.
NotImplementedError — виникає, коли абстрактні методи класу вимагають перевизначення в дочірніх класах.
SyntaxError — синтаксична помилка.
IndentationError — неправильні відступи.
TabError — змішування у відступах табуляції і пробілів.
SystemError — внутрішня помилка.
TypeError — операція застосована до об’єкту невідповідного типу.
ValueError — функція отримує аргумент правильного типу, але некоректного значення.
UnicodeError — помилка, пов’язана з кодуванням / розкодуванням Unicode в рядках.
UnicodeEncodeError — виняток, пов’язаний з кодуванням Unicode.
UnicodeDecodeError — виняток, пов’язаний з декодуванням Unicode.
UnicodeTranslateError — виняток, пов’язаний з перекладом Unicode.
Warning — попередження.
Тепер, знаючи, коли і за яких обставин можуть виникнути виключення, можна їх обробляти. Для обробки виключень використовується конструкція try ... except.
Перший приклад застосування цієї конструкції:
try:
k = 1 / 0
except ZeroDivisionError:
k = 0
print(k)
0
У блоці try виконується інструкція, яка може породити виняток, а у блоці except — перехоплюється. При цьому перехоплюються як саме виняток, так і його нащадки. Наприклад, перехоплюючи ArithmeticError, також перехоплюються FloatingPointError, OverflowError і ZeroDivisionError.
try:
k = 1 / 0
except ArithmeticError:
k = 0
print(k)
0
Також можлива інструкція except без аргументів, яка перехоплює взагалі все (і переривання з клавіатури, і системний вихід і т. д.). Тому у такій формі інструкція except практично не використовується, а використовується except Exception. Однак найчастіше перехоплюють виключення по одному, для спрощення налагодження (раптом буде здійснена помилка, а except її перехопить).
Ще дві інструкції — це finally і else. finally виконує блок інструкцій у будь-якому випадку, чи було виключення, чи ні (застосовні, коли потрібно неодмінно щось зробити, наприклад, закрити файл). Інструкція else виконується у тому випадку, якщо виключення не було.
f = open('1.txt')
ints = []
try:
for line in f:
ints.append(int(line))
except ValueError:
print('Це не число. Виходимо')
except Exception:
print('Це що ще таке?' )
else:
print('Все добре.')
finally:
f.close()
print('Я закрив файл.')
#Саме у такому порядку: try, група except, потім else, і тільки потім finally.