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

My Code Isn't Working

@pythonforbiologists.com

В цій статті опишу 5 найпоширеніших помилок. Це допоможе вам навчитися на чужих помилках, набити менше гуль на власній голові та швидше освоїти мову.

Отже:

1. Неправильні відступи

З відступами ніби все зрозуміло на перший погляд. Зазвичай це має бути 4 пробіли. Кожен блок коду, будь-то функція чи клас, чи вкладений оператор, мають свій додатковий відступ всередині свого тіла.

Але досить часто початківці міксують пробіли з табуляцією. Замість чотирьох пробілів у їхньому коді часто зустрічається табуляція. Найгірший варіант це, коли табуляція йде з пробілами в перемішку. Таким чином деколи отримуємо непрацюючий код, недійсний синтаксис.

Щоб уникати цієї проблеми рекомендую налаштувати власний редактор, щоб він використовував лише пробіли при відступах. І щоб один таб замінявся ним на 4 пробіли також. Якщо ж ваш редактор цього не дозволяє зробити – час пошукати новий, кращий 😉

2. Використання ключового слова в якості змінної

Через брак знань ключових слів у мові Пітон початківці часто використовують (зазвичай випадково) їх у власних програмах в якості змінних.

Наприклад, наступний код видасть синтаксичну помилку:

Щоб уникати даної проблеми варта ознайомитися із списком ключових слів в Python і в майбутньому уникати їх використання не за призначенням.

Подібною є проблема з використанням вбудованих Пітон функцій та змінних в якості власних змінних в програмі. І тут цю проблему може бути виявити складніше, ніж з проблемним використанням ключових слів. Якщо неправильно використовуєте ключове слово, ви негайно отримаєте Invalid Syntax помилку при запуску власної програми.

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

У наступному прикладі ми перевизначили вбудовану функцію ‘str’, яка повертає стрічкове представлення переданого їй об’єкта:

Так, у Пітоні можна “перебити” вбудовану функцію чи клас, і звичайно з цього моменту ваша програма перестане працювати коректно. Але Пітон тихо “з’їсть” даний код і буде працювати.

Як рішення до даної проблеми: використовувати унікальні назви для ваших фунцій та класів. Також варта ознайомитися з вбудованими Пітон функціями, щоб уникати подібних проблем у власному коді.

3. Зміна списку в процесі ітерації

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

Розглянемо наступний приклад, в якому доступаємося до елементів списку через індекси, і в якому пробуємо видалити кожен непарний елемент зі списку:

В такому випадку краще створити копію списка, з якого видаляти необхідні елементи, а пробігатися далі по оригінальному незмінюваному списку:

4. Простір імен

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

В Пітоні використовується правило LEGB, яке розшифровується як Локальні (Local), Вкладені (Enclosing), Глобальні (Global) та Вбудовані (Built-in) змінні.

Наведу дві найпоширеніші помилки початківців щодо правил простору імен.

1. Локальні змінні у функціях

Одразу приклад:

Спробуйте перенабрати даний приклад у себе в інтерактивному інтерпретаторі і переконаєтеся у поломці даного коду.

Чому так? Якщо ви намагаєтеся присвоїти змінній значення всередині функції (чи іншого вкладеного блоку коду), Пітон інтерпретатор автоматично розглядає дану змінну як локальну. І оскільки вираз x += 1 це по-суті є виразом x = x + 1, то Пітон пробує визначити нову змінну x локальну, якій призначити значення x + 1, в той час як локального x ще не було визначено.

Як варіант можна користуватися ключовим словом global. Але я рекомендую уникати даний підхід, і краще передавати у функцію глобальні змінні напряму як аргументи:

Такий код простіший та очевидніший для вас і для ваших колег.

2. Змінні при роботі із списками

Подібна, але ще цікавіша ситуація виникає, якщо спробувати повторити експеримент із списками:

Застосувавши ту ж саму логіку для пояснення з поперднього прикладу, ви мабуть здогадаєтеся чому func1 спрацювала добре, а func2 поламалась.

func1 – не визначала змінної локальної numbers, а лише додала новий елемент до глобального списку.

func2 – зробила numbers += [5], що по-суті є numbers = numbers + [5]. А це перевизначає локальну змінну numbers із спробою присвоєння знову ж таки локальної, ще не визначеної, змінної numbers.

Рішення? Аналогічне попередньому: передавайте глобальні змінні як аргументи функції під час виклику. Також уникайте однакових імен змінних у функціях та вкладених блоках коду.

5. Змінювані аргументи функції

Ця остання поширена помилка у нашому списку популярна не лише серед початківців. Я сам дізнався про цей нюанс мови, вже коли довший час працював і непогано володів мовою. Дізнався набивши кілька шишок в реальному проекті.

В Пітоні є класна штука – функції дозволяють визначення дефолтних значень аргументів. Наприклад, розглянемо наступну функцію:

Ніби все виглядає ок? А тепер давайте кілька разів запустимо дану функцію не передаючи їй аргументів:

Здивовані? Я також був, коли вперше побачив таке.

Справа у тому, що ми всередині функції змінюємо переданий (чи дефолтний) список. А пітон інтерпретатор встановлює дефолтний параметер фунції лише раз – коли ініціалізує дану функцію. Тобто кожен наступний раз при виклику функції ми отримуватимемо значення аргументу рівне попередньо встановленому.

Дана проблема не виникає, якщо постійно передавати аргумент на місце дефолтного списку. Але тоді втрачається зміст дефолтних значень для аргументів функцій.

Як одне із рішень може бути наступний код, коли ми перевіряємо чи значення було передане у функцію:

Таким чином, якщо у фунцію не передали параметер, ми його дефолтне значення встановлюємо у початкове – порожній список.

Як уникати інших частих помилок

До кожного типу помилки перечислених у даній статті я спробував навести для вас рекомендації щодо їх уникнення.

Крім того у початківців часто трапляються інші дрібні помилки:

  • забули двокрапку
  • забули імпорт функції чи класу
  • використання різних лапок на початку та в кінці стрічки
  • неправильна назва функції чи змінної, використання ключових слів
  • невірний синтаксис

На щастя існують утиліти, що дозволяють більшість даних помилок виявити ще до запускку коду:

  • pyflakes – перевіряє ваш код на синтаксичні помилки, зайві чи бракуючі імпорти та змінні;
  • pylint – складніший аналізатор коду, який також включає валідацію та підказки щодо стилю коду.

Надіюсь матеріал даної статті допоможе вам уникати поширених помилок та швидше освоїти цю чудову мову програмування Python.

А які помилки вам траплялися на етапі вивчення мови Python?