PEP 8

Python, подобно живому организму, развивается и приобретает новые возможности благодаря многочисленному международному сообществу согласно определенным правилам и стандартам PEP. PEP — Python Enhancement Proposal, предложения по развитию Python. Эти стандарты позволяют создавать унифицированную проектную документацию для новых утвержденных возможностей языка Python. Самый известный PEP имеет восьмой порядковый номер. PEP8 содержит перечень принципов написания красивого и лаконичного программного кода на языке Python.

Под названием каждого подраздела главы будет находиться по одному из 19 принципов философии Python (Zen of Python). Попытайтесь «прочувствовать» то, что имел в виду автор. Также, если хочется, вместо русской адаптации этих постулатов, увидеть оригинальный текст Тима Петерса, можно запустив вот такую программу.

import this

Для чего придуман PEP8?

(Читаемость имеет значение)

PEP8 существует, чтобы улучшить «читабельность» кода. Но почему этот параметр имеет настолько большую важность? Почему написание хорошо читаемого кода — один из фундаментальных принципов языка Python?

Как сказал создатель Python, Гвидо Ван Россум: «Код читается гораздо чаще, чем пишется». Вы можете провести несколько минут, или весь день, в процессе написания куска кода для, к примеру, аутентификации пользователя. Написав его, однажды, вы не будете писать его еще раз. Но вы точно вернетесь, чтобы прочитать его еще и еще раз. Эта часть кода может быть частью проекта, над которым вы работаете. Каждый раз, возвращаясь к этому файлу, придется вспомнить, что этот код делает и почему вы написали это именно так.

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

Соблюдение PEP8 особенно важно, если вы в поисках вакансии python-разработчика. Чистый и читаемый код показывает высокий профессионализм. Он говорит работодателю о вашем понимании правильного структурирования программного кода.

Если же вы более опытный Python-программист, тогда с помощи PEP8 можно с легкостью объединиться с другими программистами для работы над одной задачей. Хорошо читаемый код имеет в данном случае особую критичность. Люди, ранее не видевшие вас, но знакомые с вашим кодом, будут читать, понимая идею, которую вы хотели донести.

Негласная договоренность об именах

(Явное лучше, чем неявное)

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

Не использовать одиночные буквы l, O, или I в качестве каких-либо имен из-за риска спутать их с 1 и 0, в зависимости от шрифта.

O = 2  # Это может выглядеть так, будто вы хотите приравнять 2 к нулю.

Стили именования

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

Тип Соглашение об именовании Примеры
Функции Используйте слово или слова в нижнем регистре. Для удобства чтения разделяйте слова подчеркиванием. function, my_function
Переменные Используйте одну строчную букву, слово или слова. Для удобства чтения разделяйте слова подчеркиванием. x, var, my_variable
Классы Каждое слово начинайте с заглавной буквы. Не разделяйте слова подчеркиванием. Этот стиль называется «дело верблюда». Model, MyClass
Методы Используйте слово или слова в нижнем регистре. Для удобства чтения разделяйте слова подчеркиванием. class_method, method
Константы Используйте одну заглавную букву, слово или слова. Для удобства чтения разделяйте слова подчеркиванием. CONSTANT, MY_CONSTANT, MY_LONG_CONSTANT
Модули Используйте короткие слова или слова в нижнем регистре. Для удобства чтения разделяйте слова подчеркиванием. module.py, my_module.py
Пакеты Используйте короткие слова или слова в нижнем регистре. Не разделяйте слова подчеркиванием. package, mypackage
Помимо выбора правильных стилей именования в вашем коде, вы также должны тщательно выбирать сами имена. Ниже приведены несколько советов, как сделать это максимально эффективно.

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

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

При именовании переменных у вас может возникнуть соблазн выбрать простые, состоящие из одной буквы имена в нижнем регистре, например x. Но если вы не используете x в качестве аргумента математической функции, непонятно, что представляет собой этот самый x. Представьте, что вы храните имя человека в виде строки и хотите использовать срез строки, чтобы по-другому отформатировать его имя.

Вы можете получить что-то вроде этого:

# Не рекомендуется
x = 'Иван Петров'
y, z = x.split()

Это будет работать, но вам нужно будет отслеживать, что представляют собой x, y и z. Это также может сбивать с толку соавторов. Более правильный выбор имен будет примерно таким:

# Рекомендуется
name = 'Иван Петров'
first_name, last_name = name.split()

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

# Не рекомендуется
def db(x):
    return x * 2

На первый взгляд, это может показаться очевидным выбором — это ведь отличное сокращением для double! Но представьте, что вернетесь к этому коду через несколько дней. Скорее всего, вы забудете, какой смысл вкладывали в эту функцию и вполне можете подумать, что это сокращение от database.

Следующий пример еще более понятен:

# Рекомендуется
def multiply_by_two(x):
    return x * 2

Та же самая философия относится и ко всем прочим типам данных и объектов в Python. Всегда пробуйте использовать наиболее емкие и лаконичные названия.

Расположение кода

(Красивое лучше, чем уродливое)

То, как Вы расположите ваш код, имеет огромную роль в повышении его читаемость. В этом разделе вы узнаете, как добавить вертикальные пробелы для улучшения восприятия вашего кода. Вы также узнаете, как правильно пользоваться ограничением в 79 символов на строку, рекомендованным в PEP8.

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

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

class MyFirstClass:
    pass


class MySecondClass:
    pass


def top_level_function():
    return None

Обособьте определения методов внутри классов одной пустой строкой. Внутри класса все функции связаны друг с другом. Рекомендуется оставлять между ними только одну строку:

class MyClass:
    def first_method(self):
        return None

    def second_method(self):
        return None

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

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

def calculate_variance(number_list):
    sum_list = 0
    for number in number_list:
        sum_list = sum_list + number
    mean = sum_list / len(number_list)

    sum_squares = 0
    for number in number_list:
        sum_squares = sum_squares + number**2
    mean_squares = sum_squares / len(number_list)

    return mean_squares - mean**2

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

Максимальная длина строки и разрыв строки

PEP8 предлагает ограничить длину строки 79 символами. Это рекомендуется делать, чтобы вы имели возможность открывать несколько файлов рядом друг с другом, а также избегать переноса строк.

Конечно, не всегда возможно обеспечить длины всех операторов до 79 символов. PEP8 также описывает способы, позволяющие операторам занимать несколько строк. Python предполагает наличие продолжения строки, если код заключен в круглые, квадратные или фигурные скобки:

def function(arg_one, arg_two,
             arg_three, arg_four):
    return arg_one

Если продолжение строки использовать не представляется возможным, можно также использовать обратную косую черту для разрыва строки:

from mypkg import example1, \
    example2, example3

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

Отступы

(Должен быть один очевидный способ сделать это)

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

x = 2
if x > 6:
    print('x больше, чем 6')

Отступ перед оператором вывода дает сигнал Python об условном выполнении только в случае, когда оператор if возвращает True. Ровно такой же отступ покажет Python, какой именно код выполнять при вызове функции или какой код имеет отношение к данному классу. Ключевых правил расстановки отступов всего два и они ниже:

  1. Используйте четыре последовательных пробела для отступа;
  2. Отдавайте предпочтение пробелам, а не табуляции.

Пробелы против Табуляции

Вы можете настроить ваш редактор кода на вставку четырех пробелов, когда вы нажимаете клавишу Tab.Также необходимо иметь в виду, что в Python 3 запрещено смешение пробелов и табуляции. Изначально выберите, как именно вы будете выставлять отступы и придерживайтесь этого выбора. Иначе, вместо выполнения кода, вы получите ошибку.

Комментарии

(Если реализацию трудно объяснить, это была плохая идея)

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

  1. Используйте длину комментариев при документации не более 72 символов;
  2. Не используйте сокращения, начинайте предложения с заглавной буквы;
  3. Не забывайте актуализировать комментарии, при изменении кода.

Пример простейшего комментария:

name = 'John Smith'  # Student Name

Пробелы в выражениях и утверждениях

(Разреженное лучше, чем плотное)

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

Окружите следующие бинарные операторы одним пробелом с каждой стороны:

  1. Операторы присвоения (=, +=, -= и т. п.)
  2. Сравнения (==, ≠, >, <. ≥, ≤) и (is, is not, in, not in)
  3. Логические (and, or, not)

Когда = используется для присвоения значения для аргумента функции, не окружайте его пробелами.

Рекомендации программисту

(Простое лучше сложного)

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

# Не рекомендуется
my_bool = 4 > 3
if my_bool == True:
    return '4 больше 3'

Использование оператора эквивалентности здесь не имеет необходимости, my_bool может иметь только два значения,True или False. Поэтому достаточно написать так:

# Рекомендуется
if my_bool:
  return '4 is bigger than 3'

Этот способ выполнения оператора if с логическим оператором проще и требует меньше кода, поэтому PEP8 рекомендует именно его.

Когда лучше проигнорировать PEP8

Однозначно ответить на этот вопрос довольно сложно. Если вы безукоризненно исполняете все предписания PEP8, можно с уверенностью гарантировать «чистоту», высокий уровень читаемости кода и профессионализм программиста. Что принесет пользу всем взаимодействующим с вашим кодом, от коллег до конечного заказчика продукта. Но все же некоторые рекомендации PEP8 неприменимы в следующих случаях:

  1. Если соблюдение PEP8 нарушит совместимость с существующим программным обеспечением;
  2. Если код, сопутствующий тому, над чем вы работаете, несовместим с PEP8;
  3. Если код нужно оставить совместимым с неактуальными версиями Python.

Заключение

Теперь вам должно стать понятны способы создания высококачественного, читаемого кода Python, с помощью рекомендаций PEP8. Хотя они могут показаться тюрьмой для мозга творца, их соблюдение действительно может «прокачать» ваш код, в частности, когда речь заходит о разделении работы над ним с соавторами.

Если же у вас имеется желание углубиться в изучение тонкостей PEP8, можно ознакомиться с полной англоязычной документациейили посетить информационный ресурс pep8.org, содержащий ту же информацию, в более структурированном виде. В этих документах вы найдете, не попавшие в эту «выжимку», рекомендации.