Красивое оформление кода python

PEP8 для Python — правила красивого кода

Рассказываем, что такое стандарты PEP8 для языка Python и как их применять.

Почему важна читабельность кода

Сообщество приняло набор стилевых рекомендаций PEP8, который Гвидо ван Россум, создатель языка, предложил еще в 2001 году. Как применять и когда отступать — рассказываем в этой статье.

Что такое стандарты PEP8 для языка Python

С предсказуемым кодом приятно работать: сразу понятно, где импортированные модули, константа здесь или переменная и в каком блоке текущая строка. Для предсказуемости важны стиль и оформление, особенно в Python, который многое прощает разработчику.

Требования PEP8 по оформлению Python-кода

Единообразие, наглядность и информативность — это основа PEP8. Страница с текстом предложения постоянно дополняется, рекомендуем иногда перечитывать.

Структура кода

В Python внутренние блоки кода выделяются отступами, а не специальными разделителями. Размер отступа — четыре пробела, табуляция не используется:

if (expression_is_true): do_this() elif (other_expression_is_true): do_that() else: do_something_else()

Для удобства настройте табуляцию в любимом редакторе на проставление четырех пробелов.

Аргументы функций переносятся на следующую строку и выравниваются, если строка слишком длинная:

def long_func (arg_one, arg_two, arg_three, arg_four) def extra_long_function_name ( arg_one, arg_two, arg_three, arg_four): do_something()

Некоторые редакторы при переносе строки добавляют спецсимвол, поэтому вместо стандартных 80 символов максимальная длина строки в PEP8 — 79. Комментарии и документация — 72 символа.

Максимальную длину строки разрешается увеличить до 99 символов, если стандартные 79 ухудшают читаемость кода.

Знаки операций ставятся после переноса строки:

total_users = (currently_online + offline_but_active + offline_inactive - duplicate_accounts - banned)

Между функциями верхнего уровня и классами вставляются две пустые строки. Между определениями методов в классе — одна пустая строка. Разрешается добавлять пустые строки между логическими секциями, но не злоупотребляйте этим:

do_stuff() do_similar_stuff() do_different_stuff() do_something_else_entirely()

Правила выбора имен

По правильно названной переменной или функции сразу понятно, зачем они нужны: в first_name лежит имя, а calculate_employee_salary() считает зарплату сотрудника.

Старайтесь использовать полные имена. Их проще читать, а с сокращениями вы и сами потом с трудом разберетесь:

# Правильно first_name = ‘Ivan’ last_name = ‘Ivanov’ def plus_one (x): return x + 1 # Неправильно fnm = ‘Ivan’ lnm = ‘Ivanov’ # Plus 1? Phase 1? Point 1? def p1 (x): return x + 1

Придерживайтесь этих стилей именования:

Тип Рекомендация Примеры
Функция Одно или несколько слов в нижнем регистре, нижние подчеркивания для улучшения читаемости (snake case) function, add_one
Переменная Одна буква, слово или несколько слов в нижнем регистре, нижние подчеркивания для улучшения читаемости x, connection, first_name
Класс Одно или несколько слов с большой буквы без пробелов (camel case) Image, UserData
Метод Одно или несколько слов в нижнем регистре, нижние подчеркивания для улучшения читаемости draw(), get_user_data()
Константа Одна буква, слово или несколько слов в верхнем регистре, нижние подчеркивания для улучшения читаемости PI, MAX_CONNECTIONS
Модуль Короткое слово или слова в нижнем регистре, нижние подчеркивания для улучшения читаемости module.py, user_data.py
Пакет Короткое слово или слова в нижнем регистре без подчеркиваний package, userdata

Проверка истинности без знаков равенства

Условия с булевыми значениями проверяются без оператора эквивалентности (==):

# Правильно if this_is_true: do_something() if not this_is_false: do_something_else() # Неправильно if this_is_true == True: do_something() if this_is_false == False: do_something_else()

Сравнение с None делается с помощью операторов is / is not:

if connection is None: print_error_message() if user is not None: get_user_data()

Пустой массив, список, словарь или строка — это False. С содержимым — уже True:

first_name = ‘’ if not first_name: do_something () # выполнится colors = [‘red’] if colors: do_something_else() # выполнится

Использование комментариев

Хороший комментарий — полезный комментарий. Пользуйтесь простым и понятным языком и не забывайте обновлять их, если код меняется. Рекомендации PEP8:

  1. Пишите полные предложения с заглавной буквы, если это не название.
  2. Ставьте два пробела после точки в комментариях, кроме последнего предложения.
  3. Пишите на английском, если читатели не знают ваш язык.

Блочные комментарии объясняют следующий за ними участок кода. Выравнивайте их на том же уровне и начинайте каждую строку с # и пробела. Параграфы в блочных комментариях разделяются строкой с одной #:

# Returns a filled UserData object for the current user ID if user exists, None otherwise. Assumes database connection is already open # # TODO: very poor performance, rewrite it! def get_user_data (db_connection, user_id)

Не злоупотребляйте комментариями на той же строке (внутренними). Они не должны объяснять очевидных вещей и затруднять чтение кода. Отделяйте их от текста как минимум двумя пробелами и начинайте с # и пробела:

# Правильно first_name = ‘Ivan’ # test user, shouldn’t show up in prod # Неправильно first_name = ‘Ivan’ # first name

Пишите документацию для всех публичных модулей, функций, классов и методов. В приватных можно ограничиться комментариями, зачем они нужны и как используются.

В многострочных комментариях “”” в конце переносится на новую строку:

“””Run the provided database request. Scalar only! For everything else, use db_query(). “””

В однострочных комментариях открывающие и закрывающие “”” — на той же строке:

“””Flush buffer and close the file”””

Выражения и инструкции

Стандартная кодировка для Python 3 — UTF8. В Python 2 — ASCII, которая не поддерживает кириллицу. Пользуйтесь Windows 1251 или аналогами:

# coding: cp1251 print (“Текст кириллицей”)

Импортируйте модули в начале файла, сразу после верхнеуровневых комментариев и строк документации. Группируйте их и разделяйте группы пустыми строками: сначала стандартная библиотека, потом — сторонние, в конце — локальные модули проекта. При импорте каждый модуль пишется с новой строки. Совмещайте несколько импортов из одного модуля:

import os from math import pi, sin

Разделяйте условия, циклы и обработку исключений на отдельные строки, кроме тривиальных случаев:

# Правильно if this_is_true and that_is_true and something_else_is_true: do_stuff(); do_other_stuff(); # Допустимо if file_position < 0: file_position = 0 # file system quirk # Неправильно if this and that and something_else: do_stuff(); do_other_stuff()

Использование запятых

Кортеж из одного элемента отделяется запятой и берется в скобки для улучшения читаемости. Для систем контроля версий элементы в списке пишутся с новой строки и отделяются запятыми, если список будет расширяться. В остальных случаях запятые не ставятся:

# Правильно TEST_USERS = (‘ivanov_i’, ) TEST_ACCOUNT_IDS = [ ‘123’, ‘456’, ] # Неправильно TEST_USERS = ‘ivanov_i’, TEST_ACCOUNT_IDS = [‘123’, ‘456’, ]

Рекомендации по программированию

Определяйте функции с аннотациями типов аргументов и возвращаемых значений. Стрелка окружается пробелами с обеих сторон:

def sum(a: int, b: int) -> int: return a + b

Для типов переменных вставляйте один пробел после двоеточия. Знак присваивания окружается пробелами с обеих сторон:

# Правильно user_count: int class UserData: first_name: str = ‘replace_me’ login_and_password_hash: Tuple[str, str] # Неправильно user_count:int user_count : int class UserData: first_name: str=’’

Не забудьте указать специальный комментарий, чтобы автоматические проверки игнорировали файл, если в проекте используются любые другие виды аннотаций:

По умолчанию интерпретаторы Python должны игнорировать проверку типов и сохранять такое же поведение, как и без аннотаций. Линтеры и другой инструментарий — опциональны.

Другие рекомендации, на которые стоит обратить внимание:

  1. Используйте стандартную библиотеку, а не конкретную имплементацию (PyPy, CPython и т. д.).
  2. Реализуйте все операторы (__eq__, __ne__, __lt__, __le__, __gt__, __ge__) для сравнения элементов, не доверяйте внешнему коду в использовании только одного или нескольких.
  3. Определяйте функции ключевым словом def, а не знаком равенства: равенство оставляйте для лямбд.
  4. Наследуйте исключения от Exception вместо BaseException: BaseException зарезервировано для исключений, ловить которые — плохая идея.
  5. Сохраняйте стек вызовов при обработке цепочки исключений.
  6. Обрабатывайте конкретное исключение: слишком широкое условие (или пустой оператор except) поймает больше, чем нужно.
  7. Минимизируйте количество кода в try-блоке: в длинных условиях легче потеряться или проглотить ошибку.
  8. Очищайте локальные ресурсы с помощью with или try/finally.
  9. Вызывайте методы в менеджерах контекста явно. Исключение — резерв или возврат ресурса.
  10. Возвращайте единообразные значения: либо везде пустой return, либо везде результат или None.
  11. Проверяйте префиксы и суффиксы строк с помощью .startswith() и .endswith().
  12. Сравнивайте типы объектов через isinstance().
  13. Избегайте строковых литералов с пробельными символами в конце: некоторые редакторы и модули их обрежут.

Как проверить код на соответствие стандартам PEP8

Ручная проверка плохо подходит даже для небольших проектов: отнимает время, легко ошибиться. Используйте готовые инструменты:

  1. Среды разработки, например PyCharm.
  2. Pylint — для статического анализа и проверки стиля.
  3. Flake8 — для проверки стиля.

Pylint, Flake8 и многое другое лежит в разделе Python Code Quality Authority на гитхабе.

Когда можно проигнорировать соблюдение стандартов

Когда соблюдение стандартов ухудшает код. Помните: единообразный код понятнее и лучше читается. Например, PEP8 не применяется, если проект не доступен публично и уже использует другой стиль — или разрабатывался под старые версии Python. Для публичных библиотек PEP8 обязателен.

В проектах без единого стиля — договоритесь с командой и берите PEP8.

Коротко о главном

  1. Пишите единообразный код: его приятнее читать и легче воспринимать. PEP8 — стилевой стандарт сообщества.
  2. Выравнивайте блоки кода и отделяйте логические секции пустыми строками.
  3. Выбирайте понятные и однозначные имена для объектов.
  4. Добавляйте полезные комментарии. Обновляйте их, когда код меняется.
  5. Обрабатывайте исключения с узкими и краткими условиями.
  6. Берите автоматические инструменты проверки.
  7. Игнорируйте стандарты, если их соблюдение ухудшит код.

Источник

Читайте также:  Exception classes and common exceptions in java
Оцените статью