Винятки в 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
— базовий клас для винятків, пов’язаних з підключеннями.
BrokenPipeError
ConnectionAbortedError
ConnectionRefusedError
ConnectionResetError
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.