Кожен програміст, незалежно від досвіду, стикається з помилками під час розробки програмного забезпечення. Ці неточності можуть виникати з різних причин: від логічних прорахунків у коді, які призводять до несподіваних результатів, до порушень синтаксичних правил мови програмування, а також помилок, що виникають під час виконання програм. Усі ці збої узагальнено називають програмними помилками.
Помилки – це звичайне явище у будь-якій мові програмування, незалежно від її простоти чи складності.
Наприклад, Python, відомий своєю читабельністю та чітким синтаксисом, не звільняє розробників від програмних помилок. Незважаючи на те, що ця мова вважається досить легкою для вивчення та застосування порівняно з багатьма іншими, ви все одно можете зіткнутися з різними видами помилок при написанні коду.
Оскільки помилки є неминучими, одним з найкращих способів їх подолання є вивчення різних типів помилок та їхніх причин. Це дозволить вам не тільки уникнути їх у майбутньому, але й ефективно їх виправляти при виникненні.
Нижче наведено перелік поширених помилок у Python, з якими ви можете зіткнутися у процесі написання коду:
Синтаксичні помилки (SyntaxErrors)
Синтаксична помилка виникає, коли написаний вами код порушує правила синтаксису мови програмування. Вона робить рядок коду недійсним та таким, що не може бути інтерпретований.
Наприклад, в Python, при виведенні рядка на екран, він повинен бути укладений в лапки. Відсутність лапок призведе до виникнення синтаксичної помилки.
Синтаксичні помилки також можуть виникати через пропущені відкриваючі або закриваючі дужки (круглі, квадратні чи фігурні), неправильне написання ключових слів або назв функцій, відсутність двокрапки в кінці операторів управління потоком або пропущені необхідні оператори у виразах.
Як правило, синтаксичні помилки виникають, коли ви порушуєте правила написання коду Python.
## Синтаксична помилка через відсутність лапок ## навколо рядка, що виводиться print("Hello World) age = 20 ## Синтаксична помилка через відсутність двокрапки в операторі if if age > 18 print("Вік більше 18") ## Синтаксична помилка через незакриту дужку def square(x: return x * x print(square(4))
При виконанні вищенаведеного коду ви отримаєте повідомлення про помилку, подібне до наведеного нижче:
Повідомлення про помилку при запуску коду буде виглядати так:
File "/home/madici/Desktop/helloworld.py", line 1 print("Hello World) ^ SyntaxError: unterminated string literal (detected at line 1)
Щоб виправити ці помилки, необхідно дотримуватися правильного синтаксису Python, як показано нижче:
print("Hello World") age = 20 if age > 18: print("Вік більше 18") def square(x): return x * x print(square(4))
Помилки відступів (IndentationError)
На відміну від таких мов, як Java, C або C++, де фігурні дужки використовуються для розділення блоків коду, Python використовує відступи для визначення ієрархії та структури коду. Наприклад, в Java весь код, що виконується після оцінки умови оператора `if`, міститься у фігурних дужках.
В Python же, блок коду позначається відступом. Стандартний відступ у Python складається з чотирьох пробілів або однієї табуляції. Кількість пробілів не є критичною, але важливо, щоб вона залишалася сталою протягом усього коду.
Як програміст на Python, ви можете зіткнутися з помилками відступу, якщо не додасте необхідні відступи, наприклад, при написанні операторів управління або функцій, або якщо використовуєте пробіли і табуляції для відступу одночасно. Це призведе до плутанини для інтерпретатора, особливо якщо відступи розміщені неправильно або не є узгодженими по всій кодовій базі.
Нижче наведено приклад коду, який призводить до помилки відступу:
age = 20 if age > 18: print("Вік більший за 18") print("Можна керувати автомобілем") else: print("Вік менший за 18")
Повідомлення про помилки, що виникають з цього коду, показані нижче:
Повідомлення про помилку під час запуску коду виглядає так:
File "/home/madici/Desktop/helloworld.py", line 3 print("Вік більший за 18") ^ IndentationError: expected an indented block after 'if' statement on line 2
Щоб виправити цю помилку, необхідно зробити відступ у рядку після оператора `if` та переконатися, що відступ узгоджується з рештою коду, як показано нижче:
age = 20 if age > 18: print("Вік більший за 18") print("Можна керувати автомобілем") else: print("Вік менший за 18")
Помилки типу (TypeError)
У Python `TypeError` є винятком, який виникає, коли ви намагаєтеся виконати операцію з несумісними типами даних. Наприклад, спроба додати рядок і ціле число, або об’єднати рядковий тип даних з цілим числом, призведе до `TypeError`.
`TypeError` також можуть виникати при використанні функцій або методів з неправильними типами даних, при спробі використовувати не цілочисельний індекс для доступу до елементів ітерованого об’єкта, наприклад, списку, або при спробі ітеруватися по об’єкту, який не можна ітерувати.
В основному, будь-яка операція з неправильним типом даних призведе до `TypeError`.
Нижче наведено приклади операцій, які можуть спричинити `TypeError`:
# Помилка типу при об'єднанні рядка і цілого числа age = 25 message = "Мені " + age + " років." list1 = [1, "hello", 5, "world", 18, 2021] # Помилка типу через неправильне використання вбудованих методів print(sum(list1)) # Помилка типу при додаванні рядка і цілого числа num1 = 10 num2 = "16" print(num1 + num2) # Помилка типу при використанні не цілочисельного індексу list2 = ["hello", "from", "the", "other", "side"] print(list2["1"])
Повідомлення про помилки, що випливають з наведеного вище коду, показано нижче:
Приклад повідомлення `TypeError` з коду показано нижче:
File "/home/madici/Desktop/helloworld.py", line 3, in <module> message = "Мені " + age + " років." ~~~~~~~~^~~~~ TypeError: can only concatenate str (not "int") to str
Щоб усунути ці помилки, використовуйте правильні типи даних або перетворення типів, як показано нижче:
age = 25 message = "Мені " + str(age) + " років." list1 = [1, 5, 18, 2021] print(sum(list1)) num1 = 10 num2 = "16" print(num1 + int(num2)) list2 = ["hello", "from", "the", "other", "side"] print(list2[1])
Помилки атрибутів (AttributeError)
У Python помилка `AttributeError` виникає, коли ви намагаєтеся використати атрибут, який не існує в об’єкті, або викликаєте метод, який не існує в об’єкті, для якого він викликається. `AttributeError` означає, що об’єкт не має атрибута або методу, який ви намагаєтесь застосувати.
Наприклад, якщо ви викликаєте рядковий метод для цілого числа, ви зіткнетеся з `AttributeError`, оскільки метод не існує для типу об’єкта, для якого ви його викликаєте.
У прикладі нижче метод `capitalize()`, який використовується для перетворення першої літери рядка у верхній регістр, викликається для цілого числа. Це призведе до помилки атрибута, оскільки `int` не має методу `capitalize()`.
# Помилка атрибута при виклику capitalize() для цілого числа num = 1445 cap = num.capitalize() print(cap)
Запуск цього коду призводить до повідомлення про помилку, показаного нижче:
Повідомлення про помилку `AttributeError` з коду виглядає наступним чином:
File "/home/madici/Desktop/helloworld.py", line 3, in <module> cap = num.capitalize() ^^^^^^^^^^^^^^ AttributeError: 'int' object has no attribute 'capitalize'
Щоб виправити помилку `AttributeError`, переконайтеся, що метод або атрибут, який ви викликаєте, існує для типу об’єкта, для якого ви його викликаєте. У цьому випадку виклик `capitalize()` для рядкового типу даних вирішує цю проблему, як показано нижче:
Помилки імпорту (ImportError)
Помилка `ImportError` у Python виникає, коли ви намагаєтеся імпортувати модуль, який неможливо знайти або який недоступний у поточному середовищі. Це може бути через те, що модуль ще не встановлено, ви неправильно налаштували шлях до нього, або ви помилилися при введенні назви модуля.
`ImportError` має дочірній підклас `ModuleNotFoundError`, який виникає при спробі імпортувати модуль, який неможливо знайти.
Наприклад, наведений нижче код, який намагається імпортувати бібліотеку аналізу даних pandas, видасть помилку, оскільки модуль ще не встановлено.
Згенероване повідомлення `ImportError` показано нижче:
File "/home/madici/Desktop/helloworld.py", line 1, in <module> import pandas ModuleNotFoundError: No module named 'pandas'
Щоб виправити цю помилку, переконайтеся, що модулі, які ви намагаєтеся імпортувати, інстальовано. Якщо це не вирішує помилку, перевірте правильність написання назви модуля та правильність шляху до файлу для доступу до модуля.
Помилки значення (ValueError)
Це виняток, який виникає, коли функція в Python отримує значення правильного типу, але це значення не є відповідним для операції. Наприклад, функція `math.sqrt()`, яка використовується для обчислення квадратного кореня, поверне `ValueError`, якщо ви передасте їй від’ємне число.
Не зважаючи на те, що значення буде правильного типу, тобто числовим, від’ємне значення робить його непридатним для цієї функції.
Функція `int()`, яка перетворює число або рядок, поверне `ValueError`, якщо ви передасте їй рядок, що не є числовим рядком. Передача “123” або “45” до функції не призведе до помилки, оскільки ці рядки можна перетворити на цілі числа.
Однак, якщо ви передасте рядок, який не є числовим, наприклад “Hello”, ви отримаєте `ValueError`, оскільки “Hello” не має відповідного числового еквівалента.
Приклад коду, який генерує `ValueError`, наведено нижче:
# Помилка значення через неприпустиме значення в sqrt() import math num = -64 root = math.sqrt(num) print(root) # Помилка значення через передачу рядка без цілого числа в int() numString = "Hello" num = int(numString) print(num)
Помилки з вищенаведеного коду показано нижче:
Згенероване повідомлення про помилку таке:
File "/home/madici/Desktop/helloworld.py", line 4, in <module> root = math.sqrt(num) ^^^^^^^^^^^^^^ ValueError: math domain error
Щоб виправити помилку, використовуйте відповідні значення у функціях, як показано нижче:
import math num = 64 root = math.sqrt(num) print(root) numString = "5231" num = int(numString) print(num)
Помилки вводу/виводу (IOError)
`IOError` (помилка вводу/виводу) – це виняток, який виникає, коли операція введення або виведення не вдається. Це може бути спричинено спробою доступу до неіснуючого файлу, нестачею місця на диску вашого пристрою, спробою доступу до файлу, до якого у вас немає достатніх дозволів, або спробою доступу до файлу, який зараз використовується іншими процесами.
Такі методи, як `open()`, `read()`, `write()` та `close()`, які часто використовуються при роботі з файлами, можуть спричинити цю помилку.
Розглянемо наступний код, який намагається відкрити неіснуючий файл з назвою “notes.txt”. Цей код призведе до `IOError`, який спричиняє `FileNotFoundError`:
Повідомлення про помилку:
File "/home/madici/Desktop/helloworld.py", line 2, in <module> file1 = open("notes.txt", "r") ^^^^^^^^^^^^^^^^^^^^^^ FileNotFoundError: [Errno 2] No such file or directory: 'notes.txt'
Щоб уникнути цієї помилки, переконайтеся, що файл “notes.txt” існує в каталозі, з якого запущено термінал. Ще один спосіб обробки помилок вводу-виводу – це використання блоку `try…except`, як показано нижче:
Помилки імені (NameError)
Помилка `NameError` – це виняток, з яким ви зіткнетеся, коли спробуєте використати змінну, функцію або модуль, які не існують, не визначені в поточній області видимості, або яким не присвоєно значення.
Така помилка зазвичай виникає, коли ви неправильно пишете імена змінних або функцій, або коли використовуєте їх до того, як вони визначені. Використання модуля без попереднього імпорту також призведе до помилки `NameError`.
Наступний код призведе до виключення `NameError`:
# Помилка імені, бо модуль math не був імпортований num = 64 root = math.sqrt(64) print(root) # Помилка імені, бо x використовується до визначення y = 23 print(x) # Помилка імені, бо назва функції не визначена def greet(): print("Доброго ранку") great() #ameError: name 'great' is not defined
Наступні повідомлення про помилки є результатом коду вище:
Приклад повідомлення `NameError`:
File "/home/madici/Desktop/helloworld.py", line 3, in <module> root = math.sqrt(64) ^^^^ NameError: name 'math' is not defined
Щоб виправити помилку `NameError`, переконайтеся, що ви не використовуєте модулі до їхнього імпорту, змінні чи функції до їх визначення, а також правильно пишете імена функцій або змінних:
import math num = 64 root = math.sqrt(64) print(root) y = 23 print(y) def greet(): print("Доброго ранку") greet()
Помилки індексу (IndexError)
`IndexError` – це виняток, який виникає, коли ви намагаєтеся отримати доступ до індексу в списку або кортежі, що виходить за його межі. Розглянемо список нижче:
list1 = [1, 2, 3, 4, 5]
Список складається з п’яти елементів. Python підраховує індекси починаючи з 0. Таким чином, наведений вище список має індекси в діапазоні від 0 до n-1, де n – це кількість елементів у списку. В даному випадку індекси списку будуть від 0 до 4.
Якщо ви спробуєте отримати доступ до елемента з індексом, більшим за 4, ви зіткнетеся з `IndexError`, оскільки індекс виходить за межі діапазону у списку. Наступний код генерує `IndexError`:
list1 = [1, 2, 3, 4, 5] item = list1[6] # IndexError, бо індекс списку поза діапазоном print(item)
Помилка з коду показана нижче:
Згенероване повідомлення `IndexError`:
File "/home/madici/Desktop/helloworld.py", line 2, in <module> item = list1[6] # IndexError, бо індекс списку поза діапазоном ~~~~~^^^ IndexError: list index out of range
Найкращий спосіб уникнути `IndexError` – це використовувати функції `range()` і `len()`, щоб переконатися, що ви отримуєте доступ лише до елементів, які знаходяться в межах діапазону:
list1 = [1, 2, 3, 4, 5] for i in range(len(list1)): print(list1[i])
Помилки ключа (KeyError)
`KeyError` – це виняток, який виникає, коли ви намагаєтеся отримати доступ до елемента словника за допомогою ключа, якого не існує. Розглянемо словник нижче:
cities = {"Canada": "Оттава", "USA": "Вашингтон", "Italy": "Рим"}
Ключі у словнику – це “Канада”, “США”, “Італія”. Ви можете отримати доступ до елементів зі словника міст за цими трьома ключами. Однак, якщо ви спробуєте отримати доступ до елемента за допомогою ключа, якого не існує, наприклад “Бразилія”, ви отримаєте `KeyError`, як показано нижче:
Згенероване повідомлення `KeyError`:
File "/home/madici/Desktop/helloworld.py", line 6, in <module> print(cities["Бразилія"]) ~~~~~~^^^^^^^^^^ KeyError: 'Бразилія'
Щоб виправити `KeyError`, переконайтеся, що ключі, які ви використовуєте для доступу до елементів словника, дійсно присутні у ньому. Для цього можна створити умовний оператор `if…else`, наприклад:
cities = {"Canada": "Оттава", "USA": "Вашингтон", "Italy": "Рим"} country = "Канада" if country in cities: print("Столицею країни " + country + " є " + cities[country]) else: print("Ключ " + country + " відсутній у словнику міст")
Таким чином ви уникнете помилок `KeyError` під час доступу до елементів словника.
Висновок
Під час написання коду на Python, незалежно від вашого рівня досвіду, ви обов’язково зіткнетеся з помилками. Тому важливо ознайомитися з різними типами помилок, представленими в цій статті, щоб ефективно їх виправляти при виникненні.
Також рекомендуємо вивчити корисні однорядкові вирази Python, що спрощують виконання типових завдань.