Код значно частіше читають, ніж його пишуть. Тому вартує один раз постаратись при написанні (навіть ввести це у звичку), щоб усі наступні читачі комфортно могли читати ваш код, та й зрештою ви сам могли з легкістю читати власний код.
Саме тому у даній статті поговоримо про правила написання коду:
- для чого їх взагалі придумали;
- коли варта їх використовувати, а коли можна уникати;
- ну і звичайно оглянемо найважливіші з них у мові Python.
Отже:
Що таке правила стилю в коді?
Уявіть, що над проектом працює 10 людей. Одному розробнику до вподоби ставити пробіли навколо оператором дорівнює, іншому ні. Один у своєму коді використовує два пробіли для вкладених блоків коду, а інший – шість. Один називає функції у форматі кемелкейс (myNewFunction), а інший з підкресленнями (my_new_function). Одному програмісту більше подобається тримати увесь код в одному модулі, а інші розбивають його на дрібні куски коду і кладуть у різні пакети та модулі. Частина людей в проекті ставить порожній рядок між методати у класі, а інша частина – три рядка.
Уявили? Код виглядатиме кучеряво і вам прийдеться пристосовуватися до нових форматів у кожному наступному модулі, пакеті з кодом.
Щоб уникати важкого для прочитання коду якраз і придумали правила стилю в коді. І навіть не так важливо дотримуватись одних офіційних правил, як важливо тримати свій код у консистентному стані. Тобто, усюди форматуєте однаково, нехай навіть, якщо це ваші власні правила стилю коду.
В мові програмування Python є також свій гайд по стилях коду – це PEP 8. Там описані основні правила, яких варта дотримуватися при написанні Пітон коду.
Тобто, Стилі Коду – це те як виглядає ваш код. Працювати звичайно він буде і якщо не є форматованим під певні правила, але іншим людям, вашим колегам та й навіть вам, значно легше буде розібратися у ньому пізніше, якщо ви не полінувались і зберегли домовленості стилю у вашому коді.
Коли можна ігнорувати офіційні стилі коду Python?
Притримуватись PEP 8 правил – важливо. Притримуватись правил поточного проекту, над яким працюєте – ще важливіше. Притримуватись правил поточного модуля, класу чи функції – найважливіше.
Тобто, якщо ви працюєте над існуючим кодом, проектом чи пакетом, тоді не варта свій код форматувати під офіційні пітон правила, а краще дотримуватись стилів запроваджених у поточному коді, хіба що ви зібрались переписати код усього проекту.
Іншими словами: не переробляйте ремонт у всій хаті, якщо поламався краник у ванній 😉
Ще кілька причин, коли можна ігнорувати стилі коду:
- коли застосування стилів зробить ваш код важчим для прочитання;
- вже згадувана причина: якщо це порушує існуючі в навколишньому коді стилі;
- коли код повинен залишатись сумісним із старою версією Пітона, яка не підтримує нововведень стилів коду.
Інструменти для підтримки стилів коду
Початківцям зазвичай важко з першого разу писати код повністю згідно стандартів, навіть теоретично знаючи усі необхідні правила. Саме тому і придумали процедури рев’ю коду джуніків старшими програмістами.
Але, щоб ще далі полегшити життя тим, хто лише починає освоювати стилі коду, придумали цілий ряд інструментів, які автоматично перевірять код та вкажуть, і навіть поправлять знайдені проблеми:
- pep8 утиліта: вказує на проблеми у форматуванні вашого Python коду згідно PEP8 стандарту;
- Pylint: дуже потужний інструмент, який перевіряє ваш код не лише на форматування, але й на помилки, пропущені імпорти, проблеми із змінними, можливість створення UML діаграм і багато іншого;
- pyflakes: проста програма, яка перевіряє ваш код на присутність помилок.
Деякі із інструментів можна прикрутити до вашого редактора і вони спрацьовуватимуть на кожному оновленні файлика.
Думаю з даними інструментами ваше життя буде значно легшим 😉
Ну і врешті-решт перейдемо до найважливіших основних правил стилів коду у мові програмування Python:
Офіційні правила стилів мови Python
Тут наведу найважливіші правила, яких зазвичай варта дотримуватись:
- у Пітон коді використовуйте для відступів 4 пробіла, без табів (налаштуйте редактор для цього);
- максимальна довжина рядочка коду 79;
- розділяйте функції та класи верхнього рівня у модулі двома порожніми рядочками;
- розділяйте методи в класі одним рядочком;
- розділяйте порожнім рядочком логічні блоки коду всередині функції;
- не забувайте додавати utf-8 header: “# -*- coding: utf-8 -*-” , не рекомендується писати Пітон коду у інших, ніж utf-8 кодуваннях;
- надаються переваги імпортам на окремих рядочках, тобто кожен імпорт – окремий рядок;
- імпорти завжди мають бути на початку файлу;
- порядок імпортів, бажано погрупований і розділений одним порожнім рядочком: імпорти із стандартної бібліотеки, імпорти із додаткових допоміжних бібліотек, локальні імпорти з власного коду;
- надається перевага абсолютним імпортами над відносним, але відносні зручно використовувати в пакетах у разі перейменувань;
- краще уникати імпортів із зірочкою: “from my.mobuld import *“;
- уникайте пробілів навколо дужок (круглих, фігурних, квадратних): “myfunc ( arg, arg2 ); краще так: “myfunc(arg, arg2)”;
- уникайте пробілів одразу перед комою двокрапкою та крапкою з комою;
- вирівнювання хоч і гарне для ока, але також нерекомендується гайдом:
1 2 3 4 5 6 7 8 9 |
# неправильно x = 2 my_var = 3 abc = 4 # правильно x = 2 my_var = 3 abc = 4 |
- завжди оточуйте дані бінарні оператори пробілами з кожної сторони: =, +=, -=, ==, <, >, !=, <>, <=, >=, in, not in, is, is not, and, or, not;
- якщо у виразі використані оператори із різним пріоритетом, тоді можна додавати пробіли лише навколо нижче пріоритетних операторів: “a = x*2 + y*5 + z/2”;
- не оточуйте пробілами оператор присвоєння (=), якщо він використовується, щоб позначити ключовий аргумент чи дефолтне значення:
1 2 3 4 5 6 7 |
# неправильно def myfunc(x = 10): pass # правильно def myfunc(x=10): pass |
- складні вирази не бажано використовувати на одному рядочку:
1 2 3 4 5 6 7 8 9 10 |
# неправильно if foo == 'blah': do_blah_thing() do_one(); do_two(); do_three() # краще if foo == 'blah': do_blah_thing() do_one() do_two() do_three() |
- оператори if, for, while завжди краще використовувати на різних рядочках:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# не бажано if foo == 'blah': do_blah_thing() for x in lst: total += x while t < 10: t = delay() # і так точно не варта ;-) if foo == 'blah': do_blah_thing() else: do_non_blah_thing() try: something() finally: cleanup() do_one(); do_two(); do_three(long, argument, list, like, this) if foo == 'blah': one(); two(); three() |
- дуже рекомендовано використовувати коментарі в коді, кажуть навіть що краще некоректний коментар ніж ніякий ;-);
- тримайте коментарі актуальними із змінами в коді;
- коментарів повинні буде цілими закінченими реченнями
- короткий коментар може не мати крапки наприкінці;
- для блочних коментарів використовуйте ті ж відступи, що і для коду який даний коментарі пояснює;
- новий код повинен притримуватись наступних правил щодо назв імен, функцій, класів, модулів та змінних:
- імена публічного використання повинні відображати зміст їхнього використання, а не деталі імплементації;
- в Пітоні не має чіткого правила, який стиль імен використовувати; існують наступні правила назв:
* b (єдиний символ в нижньому регістрі)
* B (єдиний символ у верхньому регістрі)
* lowercase (нижній регістр)
* lower_case_with_underscores (нижній регістр з підкресленнями)
* UPPERCASE (верхній регістр)
* UPPER_CASE_WITH_UNDERSCORES (верхній регістр з підкресленнями)
* CapitalizedWords (або CapWords, or CamelCase — названий через вигляд ніби у верблюда горби, кожне слово частина почанється з великої літери)
* mixedCase (такий як CamelCase але з першим словом з маленької)
* Capitalized_Words_With_Underscores (дуже дивний стиль і маловикористовуваний); - варта уникати назв, які:
* починаються з одного або двох підкреслень;
* закінчуються одним або двома підкресленнями; - також не використовуйте літер ‘l’ та ‘O’ як назви змінних, адже в деяких шрифтах дані символи є тотожніми одиниці та нулю;
- назви пакетів та модулів:
* короткі назви
* нижній реєстр
* слова розділені підкресленням (нижнім дефісом)
* в назвах пакетів краще не використовувати нижнього дефісу; - назви класів: CamelCase зазвичай;
- назви функцій:
* нижній реєстр;
* розділені нижнім дефісом при необхідності; - назви методів та атрибутів класу:
* нижній реєстр;
* можна для читабельності також розділяти нижнім дефісом;
Ніби все по назвах, ще трохи різноманітних речей скопом:
- публічні атрибути не можуть починатися із підкреслення;
- краще використовувати “is not”, ніж “not … is”;
- краще повноцінна функція, ніж lambda;
- унаслідуйте ваші класи помилок від Exception, а не BaseExpection;
- краще перехоплювати помилки конкретного типу, аніж усі;
Є ще багато дрібних речей, але вони вже більше описують, які функції і коли краще використовувати, аніж сам вигляд та формат коду.
Згрубша прогнали основні речі, які ви повинні мати на увазі створюючи свій черговий шедевр на мові Python 🙂
Я сам використовую не усі правила, наприклад імпорти у мене йдуть в одному рядочку. Економія місця. Решту речей адаптую взалежності від проекту та фреймворка, адже вони мають вищий пріоритет. Головне – писати ваш код однаково у всьому проекті!
А ви слідуєте стилям коду? Цікаво, які мови програмування не мають офіціного гайду по стилях?
Хочете більше дізнатися про правильні практики та підходи при написанні коду на мові програмування Python? Ознайомтесь детальніше із книгою, над якою я зараз працюю:
імена публічного використання ПОВИННЯ відображати зміст їхнього використання, а не деталі імплементації;
Поправте.
дякую, виправив
Помилка в слові “нижнього”.
“в назвах пакетів краще не використовувати нижньгго дефісу”
дякую, виправив