В предыдущей статье о PEP 8 мы узнали, что это за стандарт и в чем его важность. Также мы рассмотрели, каким образом можно привести код в соответствие с этим стандартом. В этой статье переходим к разбору конкретных рекомендаций по оформлению кода на Python. Мы рассмотрим, как выбирать имена, как делать вертикальные и горизонтальные отступы в коде, как переносить строки, где ставить закрывающие скобки.
«Явное лучше неявного», — Дзен Python.
Когда вы пишете код на Python, вам нужно назвать множество вещей: переменные, функции, классы, пакеты и так далее. Выбор разумных имен сэкономит вам время и силы в дальнейшем. По названию вы сможете понять, что представляет собой определенная переменная, функция или класс. Вы также избежите использования неподходящих имен, которые могут привести к трудноисправляемым ошибкам.
Совет: никогда не используйте однобуквенные имена l, O или I, поскольку они могут быть ошибочно приняты за 1 и 0 при определённых шрифтах:
O = 2 # Выглядит так, будто вы пытаетесь присвоить нулю значение 2
В таблице ниже описаны некоторые из распространенных стилей именования в коде на Python и указаны случаи, когда их следует использовать:
Тип | Соглашение о наименовании | Примеры |
---|---|---|
Функция | Используйте слово/слова в нижнем регистре. Отделяйте слова нижним подчёркиванием. | function, my_function |
Переменная | Используйте одну букву, слово или слова в нижнем регистре. Для удобства чтения разделяйте слова нижним подчеркиванием. | x, var, my_variable |
Класс | Каждое слово начинайте с заглавной буквы. Не разделяйте слова подчеркиванием. Этот стиль называется Pascal Case. | Model, MyClass |
Метод | Используйте слово/слова в нижнем регистре. Для удобства чтения разделяйте слова подчеркиванием. | class_method, method |
Константа | Используйте одну букву, слово или слова в верхнем регистре. Для удобства чтения разделяйте слова подчеркиванием. | CONSTANT, MY_CONSTANT, MY_LONG_CONSTANT |
Модуль | Используйте короткое слово/слова в нижнем регистре. Для удобства чтения разделяйте слова подчеркиванием. | module.py, my_module.py |
Пакет | Используйте короткие слова или слова в нижнем регистре. Не разделяйте слова подчеркиванием. | package, mypackage |
Придерживайтесь выбранного стиля во всем проекте, и ваш код станет более читабельным. Также будьте осторожны при выборе букв и слов.
Стиль нейминга, безусловно, важен, но кроме того нужно тщательно выбирать сами имена. Ниже приведены несколько советов о том, как делать это максимально эффективно.
[python_ad_block]Выбор имен для ваших переменных, функций, классов и т. д. может быть сложной задачей. Хорошо подобранные имена сделают ваш код более читабельным. Лучший способ – использовать информативные имена, чтобы было понятно, что представляет собой объект.
При именовании переменных у вас может возникнуть соблазн выбрать простые однобуквенные имена в нижнем регистре, например, x
. Но если вы не используете x
в качестве аргумента математической функции, непонятно, что он собой представляет. Представьте, что вы сохраняете имя человека в виде строки и хотите использовать срез, чтобы отформатировать его по-другому. У вас может получиться что-то вроде этого:
# Не рекомендуется x = 'John Smith' y, z = x.split() print(z, y, sep=', ') 'Smith, John'
Это будет работать, но вам придётся разбираться, что собой представляют x
, y
и z
. Это также может сбивать с толку ваших коллег. Более правильный выбор имен будет примерно таким:
# Рекомендуется name = 'John Smith' first_name, last_name = name.split() print(last_name, first_name, sep=', ') # 'Smith, John'
Точно так же, в попытках уменьшить количество букв в имени, может возникнуть соблазн использовать сокращения. В приведенном ниже примере я определяю функцию db()
, которая принимает единственный аргумент x
и удваивает его:
# Не рекомендуется def db(x): return x * 2
На первый взгляд это могло показаться разумным выбором. db()
легко может быть сокращением от double
. Но представьте, что вы вернетесь к этому коду через несколько дней. Возможно, вы забыли, чего пытались достичь с помощью этой функции, и из-за этого будет сложно угадать, как вы ее сократили.
Следующий пример намного яснее. Если вы вернетесь к этому коду через пару дней после его написания, вы все равно сможете прочитать и понять назначение этой функции.
# Рекомендуется def multiply_by_two(x): return x * 2
Та же философия применяется ко всем другим типам данных и объектам в Python. Всегда старайтесь использовать как можно более краткие, но информативные имена.
«Красивое лучше уродливого», — Дзен Python.
Расположение строк вашего кода играет огромную роль в его читабельности. В этом разделе вы узнаете, как добавлять отступы, чтобы улучшить читаемость кода. Вы также узнаете, как использовать ограничение в 79 символов в строке, рекомендованное в PEP 8.
Вертикальные пробелы (т.е. пустые строки) могут значительно улучшить читаемость вашего кода. Код, который сливается в сплошной блок, сложно просматривать. Но слишком много пустых строк делают код очень разреженным, и читателю придется прокручивать его куда чаще, чем хотелось бы. Ниже приведены три основных правила использования вертикальных пробелов.
Функции и классы верхнего уровня должны быть довольно самодостаточными и реализовывать отдельные части функциональности. Имеет смысл обособить их, добавив дополнительное пространство по вертикали, чтобы было ясно, что они разделены:
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
Аккуратное использование вертикальных пробелов может значительно улучшить читаемость вашего кода. Оно помогает читателю с первого взгляда понять, как ваш код разбивается на разделы и как эти разделы соотносятся друг с другом.
PEP 8 предлагает ограничение на длину строк в 79 символов. Такая длина позволяет открывать несколько файлов рядом друг с другом, а также избегать переноса строк.
Конечно, не все предложения возможно вместить в 79 или менее символов. В PEP 8 очерчивает способы написать длинное предложение, заняв несколько строк.
Если код заключен в круглые, квадратные или фигурные скобки, Python «поймет», что это одно предложение:
def function(arg_one, arg_two, arg_three, arg_four): return arg_one
Также, если невозможно дописать код в одну строку, вы можете использовать обратную косую черту для разрыва строк:
from mypkg import example1, \ example2, example3
Однако, если вы можете продолжить писать в одну строку, вам следует это сделать.
Если разрыв строки должен произойти около бинарных операторов, таких как +
и *
, он должен произойти перед оператором. Это правило происходит из математики. Математики согласны с тем, что прерывание перед бинарными операторами улучшает читаемость. Сравните следующие два примера.
Разрыв перед бинарным оператором:
# Рекомендуется total = (first_variable + second_variable - third_variable)
Вы можете сразу увидеть, какая переменная прибавляется или вычитается, поскольку оператор находится рядом с переменной, над которой выполняется операция.
Теперь давайте посмотрим на пример разрыва после бинарного оператора:
# Не рекомендуется total = (first_variable + second_variable - third_variable)
Здесь сложнее разглядеть, какая переменная добавляется, а какая вычитается.
Прерывание строки перед бинарными операторами дает более читаемый код, поэтому PEP 8 это поощряет.
Если вы переходите на новую строку после бинарного оператора, но делаете так последовательно во всем документе (проекте), это по-прежнему соответствует PEP 8. Но всё же рекомендуется первый вариант.
«Должен быть один – и желательно только один – очевидный способ сделать что-либо», — Дзен Python.
Отступы чрезвычайно важны в Python. Уровень отступа строк кода в Python определяет, как группируются операторы.
Рассмотрим следующий пример:
x = 3 if x > 5: print('x больше 5')
Оператор print
с отступом сообщает Python, что он должен выполняться только в том случае, если if
возвращает True. Тот же отступ применяется для указания Python, какой код выполнять при вызове функции или какой код принадлежит данному классу.
Ключевые правила отступов, изложенные в PEP 8, следующие:
Как упоминалось выше, для отступа кода следует использовать пробелы вместо табуляции. Вы можете настроить параметры в текстовом редакторе таким образом, чтобы выводить 4 пробела вместо символа табуляции при нажатии клавиши Tab.
Если вы используете Python 2 и применяли сочетание табуляции и пробелов для отступа в коде, вы не увидите ошибок при попытке запустить этот код. Чтобы проверить согласованность, можно добавить флаг -
при запуске кода на Python 2 из командной строки. Если есть проблемы с использованием табуляции и пробелов, интерпретатор выдаст предупреждения:t
$ python2 -t code.py code.py: inconsistent use of tabs and spaces in indentation
Если вместо этого вы используете флаг -tt
, интерпретатор будет выдавать ошибки вместо предупреждений, и ваш код не будет запущен. Преимущество использования этого метода заключается в том, что интерпретатор сообщает вам, в чем заключаются несоответствия:
$ python2 -tt code.py File "code.py", line 3 print(i, j) ^ TabError: inconsistent use of tabs and spaces in indentation
Python 3 не позволяет смешивать табуляцию и пробелы. Поэтому, если вы используете Python 3, эти ошибки выдаются автоматически:
$ python3 code.py File "code.py", line 3 print(i, j) ^ TabError: inconsistent use of tabs and spaces in indentation
При написании кода на Python для создания отступов можно использовать табуляцию, а можно и пробелы. Но если речь идет о Python 3, вы должны быть последовательны в своем выборе. В противном случае ваш код не запустится. PEP 8 рекомендует всегда использовать 4 последовательных пробела для обозначения отступа.
Когда вы используете продолжение строки, чтобы длина строки не превышала 79 символов, полезно использовать отступ для улучшения читаемости. Это позволяет различать две строки кода и одну строку кода, размещенную на двух строчках. Можно использовать два стиля отступа.
Первый из них — выровнять блок с отступом по открывающей скобке:
def function(arg_one, arg_two, arg_three, arg_four): return arg_one
Иногда может оказаться, что для выравнивания по открывающей скобке требуется всего 4 пробела. Это часто происходит в операторах if
, которые охватывают несколько строк, поскольку if
, пробел и открывающая скобка составляют 4 символа. В этом случае бывает сложно определить, где внутри оператора if
начинается вложенный блок кода:
x = 5 if (x > 3 and x < 10): print(x)
В этом случае PEP 8 предоставляет две альтернативы для улучшения читаемости.
Во-первых, можно добавлять комментарии после последнего условия. Из-за подсветки синтаксиса в большинстве редакторов это отделит условия от вложенного кода:
x = 5 if (x > 3 and x < 10): # Оба условия соблюдены print(x)
Во-вторых, можно сделать дополнительный отступ в продолжении строки:
x = 5 if (x > 3 and x < 10): print(x)
Альтернативный вариант отступа после разрыва строки – висячий отступ. Это типографский термин, означающий, что каждая строка, кроме первой в абзаце или цитате, имеет отступ. Вы можете использовать такой отступ для визуального представления продолжения строки кода. Вот пример:
var = function( arg_one, arg_two, arg_three, arg_four)
Замечание. Если вы используете висячий отступ, в первой строке не должно быть аргументов. Следующий пример не соответствует требованиям PEP 8:
# Не рекомендуется var = function(arg_one, arg_two, arg_three, arg_four)
В данном случае потребуется дополнительный отступ, чтобы отличить продолжающуюся строку от кода, содержащегося внутри функции. Следующий пример трудно прочитать, потому что код внутри функции находится на том же уровне отступа, что и продолженные строки:
# Не рекомендуется def function( arg_one, arg_two, arg_three, arg_four): return arg_one
Вместо этого лучше использовать двойной отступ в продолжении строки. Это поможет вам различать аргументы функции и тело функции, улучшая читаемость:
def function( arg_one, arg_two, arg_three, arg_four): return arg_one
Когда вы пишете код, отвечающий требованиям PEP 8, ограничение в 79 символов вынуждает вас добавлять разрывы строк. Для лучшей читаемости нужно делать отступ в продолжении строки, чтобы показать, что это одна строка. Это можно сделать двумя способами. Первый — выровнять блок с отступом по открывающей скобке. Второй — использовать висячий отступ. Метод отступа после разрыва строки можно выбрать самостоятельно.
Продолжение строк позволяет нам разрывать строки внутри кавычек и различных скобок. О закрывающей скобке легко забыть, но важно поместить ее в разумное место. В противном случае читатель может запутаться. PEP 8 предлагает два варианта положения закрывающей скобки в подразумеваемых продолжениях строк.
Можно выровнять закрывающую скобку по первому не пробельному символу предыдущей строки:
list_of_numbers = [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
А можно совместить закрывающую скобку с первым символом строки, с которой начинается конструкция:
list_of_numbers = [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
Оба варианта совершенно равноправны. Но, как всегда, ключевым моментом здесь является последовательность, поэтому постарайтесь придерживаться какого-то одного из указанных методов.
Перевод части статьи How to Write Beautiful Python Code With PEP 8.
В следующей статье о PEP 8 мы разберем правила оформления комментариев, использование пробелов и выбор операторов и методов.
Pydantic - это мощная библиотека проверки данных и управления настройками для Python, созданная для повышения…
Python предлагает набор библиотек, удовлетворяющих различные потребности в визуализации, будь то академические исследования, бизнес-аналитика или…
В Python для представления данных в двоичной форме можно использовать байты. Из этой статьи вы…
В этой статье рассказывается о том, что такое Werkzeug и как Flask использует его для…
При работе с датами часто возникает необходимость прибавлять к дате или вычитать из нее различные…
В этом руководстве мы рассмотрим, как добавить социальную аутентификацию с помощью GitHub и Google в…