4  Помилки та винятки

Data Miorsh Ihor Miroshnychenko Youtube Monobank

4.1 SyntaxError

Винятки в Python, як і в інших мовах програмування, відносяться до проблем у вашому коді.

Почнемо з простого прикладу: створимо файл hello.py:

Terminal
code cat.py

Напишемо простий код з помилкою:

print("Привіт, світ!)
  Cell In[1], line 1
    print("Привіт, світ!)
          ^
SyntaxError: unterminated string literal (detected at line 1)

Ми отримали помилку SyntaxError, яка означає, що Python не зміг зрозуміти наш код. Це найпростіший вид помилки, який можна виправити, виправивши помилку в коді. Запис unterminated“, як правило, означає, що я щось почав, але не зупинив. Запис string - це послідовність символів, з якою ми вже знайомі. А literal зазвичай відноситься до того, що ви буквально набрали.

Отже вирішення цієї помилки дуже просте: додайте закриваючу лапку:

print("Привіт, світ!")
Привіт, світ!

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

4.2 ValueError

Але в Python є багато інших типів помилок, які можна назвати RuntimeError, які трапляються під час роботи вашого коду. І саме від вас залежить написання додаткового захисного коду для виявлення таких помилок.

Наприклад, давайте створимо файл number.py, яка буде приймати число від користувача і виводити це число на екран:

Terminal
code number.py
number = int(input("Введіть число: ")) # 5
print(f'Ваше число: {number}')
Ваше число: 5

Але що станеться, якщо користувач введе не число, а текст? Наприклад, введе слово п'ять:

number = int(input("Введіть число: ")) # п'ять
print(f'Ваше число: {number}')
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[4], line 1
----> 1 number = int('п\'ять')
      2 print(f'Ваше число: {number}')

ValueError: invalid literal for int() with base 10: "п'ять"

Ми отримали помилку ValueError, яка означає, що ми передали функції int() значення, яке вона не може перетворити на число. Це вже не синтаксична помилка, а помилка, яка виникає під час виконання програми. І вирішення цієї помилки вже не залежить від вас, а від користувача, який вводить дані. Тому вам потрібно написати додатковий код, який буде перевіряти введені дані на коректність. Як це зробити у Python? Виявляється у Python є ключові слова які можуть допомогти з цим.

4.3 Ключові слова try та except

Якщо ви хочете спробувати зробити щось у Python, ви можете використовувати це ключове слово try. це досить влучна назва. За рахунок нього ви можете перевірити, чи сталося щось виняткове, щось помилкове. Отже, використовуючи try, я можу спробувати щось зробити, але якщо щось піде не так, я можу замість використати ключове слово except.

Подивимось, як це працює:

try:
    number = int(input("Введіть число: ")) # п'ять
    print(f'Ваше число: {number}')
except ValueError:
    print('Ви ввели не число')
Ви ввели не число

4.4 NameError

Якби я був впевнений, що функція print() не призведе до помилки, я міг би переписати код наступним чином і отримати нову помилку:

try:
    number = int(input("Введіть число: ")) # п'ять
except ValueError:
    print('Ви ввели не число')

print(f'Ваше число: {number}')
Ви ввели не число
Ваше число: 5

Помилка NameError означає, що я використовую змінну, яка не існує. Ця помилка виникла в наслідок порядку виконання операцій. Помилка виникає в частині коду int(input("Введіть число: ")), яка знаходиться праворуч від оператора = і це приводить до того, що змінна number не створюється.

То як вирішити цю проблему? Ви можете використовувати ключове слово else.

4.5 Ключове слово else

Інтуіція ключового слова else схожа на інтуїцію ключового слова else в умовних конструкціях. Якщо в блоці try не виникає помилок, то виконується блок else.

try:
    number = int(input("Введіть число: ")) # п'ять
except ValueError:
    print('Ви ввели не число')
else:
    print(f'Ваше число: {number}')
Ви ввели не число

З мого боку трохи неввічливо відкидати вхідні дані користувача після того, як він не зміг ввести ціле число, і просто виходити з програми. Було б зручніше, якби я просто підказував або перепитував користувача знову і знову. І для цього я можу використовувати цикл while:

while True:
    try:
        number = int(input("Введіть число: ")) # п'ять
    except ValueError:
        print('Ви ввели не число')
    else:
        print(f'Ваше число: {number}')
        break

Уявіть ситуацію, що я буду намагатися отримати від користувача досить багато цифр. Було б непогано створити власну функцію, наприклад get_int(), яка буде повторювати запит на введення цілого числа, поки користувач не введе ціле число:

def main():
    number = get_int()
    print(f'Ваше число: {number}')

def get_int():
    while True:
        try:
            number = int(input("Введіть число: ")) # п'ять
        except ValueError:
            print('Ви ввели не число')
        else:
            return number

main()

4.6 Ключове слово pass

Підемо далі, і припустимо, що ми хочемо ловити помилки, але не хочемо виводити повідомлення про помилку. Для цього ми можемо використовувати ключове слово pass:

def main():
    number = get_int()
    print(f'Ваше число: {number}')

def get_int():
    while True:
        try:
            number = int(input("Введіть число: ")) # п'ять
        except ValueError:
            pass
        else:
            return number

main()

Це просто ще один механізм для обробки помилок. Іноді ви можете використовувати pass, якщо ви хочете, щоб ваш код був синтаксично правильним, але ви не хочете нічого робити, якщо виникає помилка.

Ми можемо скоротити цей код і перенести ключове слово return вище:

def main():
    number = get_int()
    print(f'Ваше число: {number}')

def get_int():
    while True:
        try:
            return int(input("Введіть число: ")) # п'ять
        except ValueError:
            pass

main()

Це дозволить дещо скоротити код, але може бути дещо складнішим для розуміння. Який варіант обрати - це вже залежить від вас.

Тепер давайте створимо більш загальний варіант цієї програми і позбудемось від жорсткого коду. Зробимо функцію get_int() більш універсальною: було б добре, якби функція main() не знала, як функція get_int() описує свої змінні. В нашому випадку це 'Введіть число', але можна було б написати 'Введіть ціле число' або 'Введіть додатнє число' або ще щось. Для цього ми додамо параметр prompt до функції get_int(), який буде використовуватися для виведення повідомлення користувачу:

def main():
    number = get_int('Введіть число: ')
    print(f'Ваше число: {number}')

def get_int(prompt):
    while True:
        try:
            return int(input(prompt)) # п'ять
        except ValueError:
            pass

main()

4.7 Винятки

Виявляється, ви можете самостійно створювати винятки за допомогою ключового слова raise у Python.

Data Miorsh Ihor Miroshnychenko Youtube Monobank