Как написать красивый код Python с помощью PEP 8

Как написать красивый код Python с помощью PEP 8

PEP 8, иногда пишется как PEP8 или PEP-8, представляет собой документ, в котором содержатся рекомендации и рекомендации по написанию кода Python. Он был написан в 2001 году Гвидо ван Россумом, Барри Варшавой и Ником Когланом. Основной задачей PEP 8 является улучшение читабельности и согласованности кода Python.

PEP расшифровывается как Python Enhancement Proposal, и их несколько. PEP - это документ, который описывает новые функции, предлагаемые для Python, и документирует аспекты Python, такие как дизайн и стиль, для сообщества.

В этом руководстве изложены основные рекомендации, изложенные в PEP 8. Он предназначен для начинающих и средних программистов, и поэтому я не затронул некоторые из наиболее продвинутых тем. Вы можете узнать об этом, прочитав полную документациюPEP 8.

By the end of this tutorial, you’ll be able to:

  • Напишите код Python, соответствующий PEP 8

  • Понять обоснование руководящих принципов, изложенных в ПКП 8

  • Настройте среду разработки так, чтобы вы могли начинать писать код Python, совместимый с PEP 8

Free Bonus:5 Thoughts On Python Mastery, бесплатный курс для разработчиков Python, который показывает вам план действий и образ мышления, который вам понадобится, чтобы вывести свои навыки Python на новый уровень.

Почему нам нужен ПКП 8

«Читаемость имеет значение.»

-The Zen of Python

PEP 8 существует для улучшения читабельности кода Python. Но почему так важна читабельность? Почему написание читаемого кода является одним из руководящих принципов языка Python?

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

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

Следование PEP 8 особенно важно, если вы ищете работу по разработке. Написание четкого, читаемого кода демонстрирует профессионализм. Он скажет работодателю, что вы понимаете, как правильно структурировать свой код.

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

Соглашения об именах

«Явное лучше, чем неявное».

-The Zen of Python

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

Note: Никогда не используйте однобуквенные именаl,O илиI, так как они могут быть ошибочно приняты за1 и0, в зависимости от гарнитуры :

O = 2  # This may look like you're trying to reassign 2 to zero

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

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

Type Соглашение об именовании Примеры

функция

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

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. Представьте, что вы сохраняете имя человека в виде строки и хотите использовать нарезку строк, чтобы по-разному форматировать его имя. Вы можете получить что-то вроде этого:

>>>

>>> # Not recommended
>>> x = 'John Smith'
>>> y, z = x.split()
>>> print(z, y, sep=', ')
'Smith, John'

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

>>>

>>> # Recommended
>>> name = 'John Smith'
>>> first_name, last_name = name.split()
>>> print(last_name, first_name, sep=', ')
'Smith, John'

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

# Not recommended
def db(x):
    return x * 2

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

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

# Recommended
def multiply_by_two(x):
    return x * 2

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

Макет кода

«Красиво лучше, чем некрасиво».

-The Zen of Python

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

Пустые строки

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

Surround top-level functions and classes with two blank lines. Функции и классы верхнего уровня должны быть достаточно самодостаточными и обрабатывать отдельные функции. Имеет смысл поместить дополнительное вертикальное пространство вокруг них, чтобы было ясно, что они разделены:

class MyFirstClass:
    pass


class MySecondClass:
    pass


def top_level_function():
    return None

Surround method definitions inside classes with a single blank line. Внутри класса все функции связаны друг с другом. Рекомендуется оставлять между ними только одну строку:

class MyClass:
    def first_method(self):
        return None

    def second_method(self):
        return None

Use blank lines sparingly inside functions to show clear steps. Иногда сложная функция должна выполнить несколько шагов перед операторомreturn. Чтобы помочь читателю понять логику внутри функции, может быть полезно оставить пустую строку между каждым шагом.

В приведенном ниже примере есть функция для расчета дисперсии списка. Это двухэтапная проблема, поэтому я обозначил каждый шаг, оставив между ними пустую строку. Перед оператором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

Однако, если вы можете использовать подразумеваемое продолжение, то вам следует это сделать.

Если разрыв строки должен произойти вокруг бинарных операторов, таких как+ и*, он должен произойти до оператора. Это правило вытекает из математики. Математики сходятся во мнении, что разрыв перед двоичными операторами улучшает читабельность. Сравните следующие два примера.

Ниже приведен пример взлома перед бинарным оператором:

# Recommended
total = (first_variable
         + second_variable
         - third_variable)

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

Теперь давайте рассмотрим пример взлома после бинарного оператора:

# Not Recommended
total = (first_variable +
         second_variable -
         third_variable)

Здесь сложнее увидеть, какая переменная добавляется, а какая вычитается.

Прерывание перед бинарными операторами создает более читаемый код, поэтому PEP 8 поощряет это. Код, которыйconsistently прерывается после бинарного оператора, по-прежнему соответствует PEP 8. Тем не менее, вам рекомендуется взломать перед двоичным оператором.

вдавливание

«Должен быть один - и желательно только один - очевидный способ сделать это».

-The Zen of Python

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

Рассмотрим следующий пример:

x = 3
if x > 5:
    print('x is larger than 5')

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

Ключевыми правилами отступления, изложенными в PEP 8, являются следующие:

  • Используйте 4 последовательных пробела для обозначения отступа.

  • Предпочитаю пробелы над вкладками.

Вкладки против пространства

Как упоминалось выше, вы должны использовать пробелы вместо табуляции при отступе кода. Вы можете настроить параметры в текстовом редакторе таким образом, чтобы вместо символа табуляции выводилось 4 пробела при нажатии клавиши[.kbd .key-tab]#Tab #.

Если вы используете Python 2 и использовали комбинацию табуляции и пробелов для отступа в своем коде, вы не увидите ошибок при попытке его запустить. Чтобы помочь вам проверить согласованность, вы можете добавить флаг-t при запуске кода Python 2 из командной строки. Переводчик выдаст предупреждения, если вы не согласны с использованием табуляции и пробелов:

$ 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, вы должны соответствовать своему выбору. В противном случае ваш код не будет работать. ПКП 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):
        # Both conditions satisfied
        print(x)
  • Добавьте дополнительный отступ на продолжение строки:

    x = 5
    if (x > 3 and
            x < 10):
        print(x)

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

var = function(
    arg_one, arg_two,
    arg_three, arg_four)

Note: когда вы используете выступающий отступ, в первой строке не должно быть никаких аргументов. Следующий пример не соответствует PEP 8:

# Not Recommended
var = function(arg_one, arg_two,
    arg_three, arg_four)

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

# Not Recommended
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
    ]

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

«Если реализацию сложно объяснить, это плохая идея».

-The Zen of Python

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

Вот несколько ключевых моментов, которые следует помнить при добавлении комментариев в код:

  • Ограничьте длину строки комментариев и строк документации до 72 символов.

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

  • Не забудьте обновить комментарии, если вы измените свой код.

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

PEP 8 предоставляет следующие правила для написания комментариев к блоку:

  • Отступ блока комментариев к тому же уровню, что и код, который они описывают.

  • Каждую строку начинайте с#, за которым следует один пробел.

  • Разделите абзацы строкой, содержащей один#.

Вот комментарий блока, объясняющий функцию циклаfor. Обратите внимание, что предложение переносится на новую строку, чтобы сохранить ограничение в 79 символов:

for i in range(0, 10):
    # Loop over i ten times and print out the value of i, followed by a
    # new line character
    print(i, '\n')

Иногда, если код очень технический, тогда необходимо использовать более одного абзаца в комментарии блока:

def quadratic(a, b, c, x):
    # Calculate the solution to a quadratic equation using the quadratic
    # formula.
    #
    # There are always two solutions to a quadratic equation, x_1 and x_2.
    x_1 = (- b+(b**2-4*a*c)**(1/2)) / (2*a)
    x_2 = (- b-(b**2-4*a*c)**(1/2)) / (2*a)
    return x_1, x_2

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

Встроенные комментарии объясняют одно утверждение в куске кода. Они полезны, чтобы напомнить вам или объяснить другим, почему необходима определенная строка кода. Вот что говорит о них PEP 8:

  • Используйте встроенные комментарии экономно.

  • Напишите встроенные комментарии в той же строке, что и утверждение, к которому они относятся.

  • Отделяйте встроенные комментарии двумя или более пробелами из оператора.

  • Начинайте встроенные комментарии с# и одного пробела, как комментарии блока.

  • Не используйте их, чтобы объяснить очевидное.

Ниже приведен пример встроенного комментария:

x = 5  # This is an inline comment

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

x = 'John Smith'  # Student Name

Здесь встроенный комментарий дает дополнительную информацию. Однако использованиеx в качестве имени переменной для имени человека - плохая практика. Встроенный комментарий не нужен, если вы переименуете свою переменную:

student_name = 'John Smith'

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

empty_list = []  # Initialize empty list

x = 5
x = x * 5  # Multiply x by 5

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

Строки документации

Строки документации или строки документации - это строки, заключенные в двойные (""") или одинарные (''') кавычки, которые появляются в первой строке любой функции, класса, метода или модуля. Вы можете использовать их для объяснения и документирования определенного блока кода. Существует целый PEPPEP 257, который охватывает строки документации, но в этом разделе вы получите сводку.

Наиболее важные правила, применяемые к строкам документации, следующие:

  • Окружите строки документации тремя двойными кавычками с каждой стороны, как в"""This is a docstring""".

  • Напишите их для всех общедоступных модулей, функций, классов и методов.

  • Поместите""", который завершает многострочную строку документации, на отдельной строке:

    def quadratic(a, b, c, x):
        """Solve quadratic equation via the quadratic formula.
    
        A quadratic equation has the following form:
        ax**2 + bx + c = 0
    
        There always two solutions to a quadratic equation: x_1 & x_2.
        """
        x_1 = (- b+(b**2-4*a*c)**(1/2)) / (2*a)
        x_2 = (- b-(b**2-4*a*c)**(1/2)) / (2*a)
    
        return x_1, x_2
  • Для однострочных строк документации оставьте""" в одной строке:

    def quadratic(a, b, c, x):
        """Use the quadratic formula"""
        x_1 = (- b+(b**2-4*a*c)**(1/2)) / (2*a)
        x_2 = (- b-(b**2-4*a*c)**(1/2)) / (2*a)
    
        return x_1, x_2

Более подробную статью о документировании кода Python см. ВDocumenting Python Code: A Complete Guide Джеймса Мертца.

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

«Разреженный лучше, чем плотный.»

-The Zen of Python

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

Пробелы вокруг бинарных операторов

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

  • Операторы присваивания (=,+=,-= и т. Д.)

  • Сравнения (==,!=,>,<. >=,<=) и (is,is not,in,not in)

  • Логические значения (and,not,or)

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

# Recommended
def function(default_parameter=5):
    # ...


# Not recommended
def function(default_parameter = 5):
    # ...

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

# Recommended
y = x**2 + 5
z = (x+y) * (x-y)

# Not Recommended
y = x ** 2 + 5
z = (x + y) * (x - y)

Вы также можете применить это к операторамif, где есть несколько условий:

# Not recommended
if x > 5 and x % 2 == 0:
    print('x is larger than 5 and divisible by 2!')

В приведенном выше примере операторand имеет самый низкий приоритет. Поэтому может быть более понятным выражениеif, как показано ниже:

# Recommended
if x>5 and x%2==0:
    print('x is larger than 5 and divisible by 2!')

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

Следующее недопустимо:

# Definitely do not do this!
if x >5 and x% 2== 0:
    print('x is larger than 5 and divisible by 2!')

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

list[3:4]

# Treat the colon as the operator with lowest priority
list[x+1 : x+2]

# In an extended slice, both colons must be
# surrounded by the same amount of whitespace
list[3:4:5]
list[x+1 : x+2 : x+3]

# The space is omitted if a slice parameter is omitted
list[x+1 : x+2 :]

Таким образом, вы должны окружить большинство операторов пробелами. Однако есть некоторые оговорки к этому правилу, например, в аргументах функций или когда вы объединяете несколько операторов в одном операторе.

Когда избегать добавления пробелов

В некоторых случаях добавление пробела может затруднить чтение кода. Слишком много пробелов может сделать код слишком разреженным и трудным для понимания. В PEP 8 приведены очень четкие примеры, когда пробелы неуместны.

Самое важное место, чтобы избежать добавления пробелов, находится в конце строки. Это известно какtrailing whitespace. Он невидим и может привести к ошибкам, которые трудно отследить.

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

  • Сразу внутри скобок, скобок или фигурных скобок:

    # Recommended
    my_list = [1, 2, 3]
    
    # Not recommended
    my_list = [ 1, 2, 3, ]
  • Перед запятой, точкой с запятой или двоеточием:

    x = 5
    y = 6
    
    # Recommended
    print(x, y)
    
    # Not recommended
    print(x , y)
  • Перед открывающей скобкой, которая запускает список аргументов вызова функции:

    def double(x):
        return x * 2
    
    # Recommended
    double(3)
    
    # Not recommended
    double (3)
  • Перед открывающей скобкой, которая начинает индекс или срез:

    # Recommended
    list[3]
    
    # Not recommended
    list [3]
  • Между запятой и закрывающей скобкой:

    # Recommended
    tuple = (1,)
    
    # Not recommended
    tuple = (1, )
  • Для выравнивания операторов присваивания:

    # Recommended
    var1 = 5
    var2 = 6
    some_long_var = 7
    
    # Not recommended
    var1          = 5
    var2          = 6
    some_long_var = 7

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

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

«Простое лучше, чем сложное».

-The Zen of Python

Вы часто обнаружите, что есть несколько способов выполнить подобное действие в Python (и любом другом языке программирования в этом отношении). В этом разделе вы увидите некоторые предложения, которые предлагает PEP 8 для устранения этой неоднозначности и сохранения согласованности.

Don’t compare boolean values to True or False using the equivalence operator. Вам часто нужно будет проверять, является ли логическое значение Истинным или Ложным. При этом интуитивно понятно сделать это с помощью заявления, подобного приведенному ниже:

# Not recommended
my_bool = 6 > 5
if my_bool == True:
    return '6 is bigger than 5'

Использование оператора эквивалентности== здесь не требуется. bool может принимать только значенияTrue илиFalse. Достаточно написать следующее:

# Recommended
if my_bool:
    return '6 is bigger than 5'

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

Use the fact that empty sequences are falsy in if statements. Если вы хотите проверить, пуст ли список, у вас может возникнуть соблазн проверить длину списка. Если список пуст, его длина равна0, что эквивалентноFalse при использовании в инструкцииif. Вот пример:

# Not recommended
my_list = []
if not len(my_list):
    print('List is empty!')

Однако в Python любой пустой список, строка или кортеж равенfalsy. Поэтому мы можем предложить более простую альтернативу вышесказанному:

# Recommended
my_list = []
if not my_list:
    print('List is empty!')

Хотя оба примера будут выводитьList is empty!, второй вариант проще, поэтому PEP 8 поддерживает его.

Use is not rather than not ... is in if statements. Если вы пытаетесь проверить, имеет ли переменная определенное значение, есть два варианта. Первый - оценить операторif с помощьюx is not None, как в примере ниже:

# Recommended
if x is not None:
    return 'x exists!'

Второй вариант - оценитьx is None, а затем получить операторif на основе результатаnot:

# Not recommended
if not x is None:
    return 'x exists!'

Хотя оба варианта будут оценены правильно, первый проще, поэтому PEP 8 поощряет его.

Don’t use if x: when you mean if x is not None:. Иногда у вас может быть функция с аргументами, которые по умолчанию равныNone. Распространенной ошибкой при проверке, присвоено ли такому аргументуarg другое значение, является использование следующего:

# Not Recommended
if arg:
    # Do something with arg...

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

# Recommended
if arg is not None:
    # Do something with arg...

Ошибка здесь заключается в предположении, чтоnot None и truthy эквивалентны. Вы могли бы установитьarg = []. Как мы видели выше, пустые списки в Python оцениваются как ложные. Таким образом, несмотря на то, что аргументarg был назначен, условие не выполняется, и поэтому код в теле оператораif не будет выполнен.

Use .startswith() and .endswith() instead of slicing. Если вы пытались проверить, была ли строкаword префиксом или суффиксом со словомcat, может показаться разумным использоватьlist slicing. Однако нарезка списка подвержена ошибкам, и вам необходимо жестко указать количество символов в префиксе или суффиксе. Кто-то, менее знакомый с нарезкой списков в Python, также не понимает, чего вы пытаетесь достичь:

# Not recommended
if word[:3] == 'cat':
    print('The word starts with "cat"')

Однако это не так удобно, как использование.startswith():

# Recommended
if word.startswith('cat'):
    print('The word starts with "cat"')

Точно так же тот же принцип применяется, когда вы проверяете суффиксы. В приведенном ниже примере показано, как проверить, заканчивается ли строка наjpg:

# Not recommended
if file_name[-3:] == 'jpg':
    print('The file is a JPEG')

Несмотря на то, что результат верный, обозначения немного неуклюжи и трудны для чтения. Вместо этого вы можете использовать.endswith(), как в примере ниже:

# Recommended
if file_name.endswith('jpg'):
    print('The file is a JPEG')

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

Когда игнорировать PEP 8

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

Однако некоторые рекомендации в PEP 8 неудобны в следующих случаях:

  • Если соблюдение PEP 8 нарушит совместимость с существующим программным обеспечением

  • Если код, над которым вы работаете, не соответствует PEP 8

  • Если код должен оставаться совместимым со старыми версиями Python

Советы и подсказки, чтобы помочь вашему коду следовать PEP 8

Нужно помнить, что ваш код соответствует требованиям PEP 8. Может быть непросто запомнить все эти правила при разработке кода. Особенно много времени требуется для обновления предыдущих проектов, чтобы они соответствовали требованиям PEP 8. К счастью, есть инструменты, которые могут помочь ускорить этот процесс. Существует два класса инструментов, которые можно использовать для обеспечения соответствия требованиям PEP 8: линтеры и автоформаторы.

Линтер

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

Лучшие линтеры для кода Python:

  • pycodestyle - это инструмент для проверки вашего кода Python на соответствие некоторым стилевым соглашениям в PEP 8.

    Установитеpycodestyle, используяpip:

    $ pip install pycodestyle

    Вы можете запуститьpycodestyle из терминала, используя следующую команду:

    $ pycodestyle code.py
    code.py:1:17: E231 missing whitespace after ','
    code.py:2:21: E231 missing whitespace after ','
    code.py:6:19: E711 comparison to None should be 'if cond is None:'
  • flake8 - это инструмент, который объединяет отладчикpyflakes сpycodestyle.

    Установитеflake8, используяpip:

    $ pip install flake8

    Запуститеflake8 из терминала, используя следующую команду:

    $ flake8 code.py
    code.py:1:17: E231 missing whitespace after ','
    code.py:2:21: E231 missing whitespace after ','
    code.py:3:17: E999 SyntaxError: invalid syntax
    code.py:6:19: E711 comparison to None should be 'if cond is None:'

    Также показан пример вывода.

Note: дополнительная строка вывода указывает на синтаксическую ошибку.

Они также доступны как расширения дляAtom,Sublime Text,https://code.visualstudio.com/docs/python/linting#flake8[Visual Studio Code], and VIM. You can also find guides on setting up Sublime Text and VIM for Python development, as well as an overview of some popular text editors at _Real Python.

Autoformatters

Автоформаторы - это программы, которые автоматически реорганизуют ваш код в соответствии с PEP 8. Однажды такой программой являетсяblack, которая автоматически форматирует код, следуяmost правил в PEP 8. Одно большое отличие состоит в том, что он ограничивает длину строки до 88 символов, а не до 79. Однако вы можете перезаписать это, добавив флаг командной строки, как вы увидите в примере ниже.

Установитеblack, используяpip. Для запуска требуется Python 3.6+:

$ pip install black

Его можно запустить через командную строку, как и с линтерами. Допустим, вы начали со следующего кода, который не соответствует PEP 8, в файле с именемcode.py:

for i in range(0,3):
    for j in range(0,3):
        if (i==2):
            print(i,j)

Затем вы можете запустить следующую команду через командную строку:

$ black code.py
reformatted code.py
All done! ✨ 🍰 ✨

code.py будет автоматически переформатирован, чтобы выглядеть так:

for i in range(0, 3):
    for j in range(0, 3):
        if i == 2:
            print(i, j)

Если вы хотите изменить ограничение длины строки, вы можете использовать флаг--line-length:

$ black --line-length=79 code.py
reformatted code.py
All done! ✨ 🍰 ✨

Два других автоформатора,autopep8 иyapf, выполняют действия, аналогичные тем, что делаетblack.

В другом руководствеReal Python,Python Code Quality: Tools & Best Practices Александра ван Тол, дается подробное объяснение того, как использовать эти инструменты.

Заключение

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

В этом уроке вы узнали:

  • Что такое PEP 8 и почему он существует

  • Почему вы должны стремиться написать PEP 8-совместимый код

  • Как написать код, совместимый с PEP 8

Кроме того, вы также узнали, как использовать линтеры и автоформаторы для проверки вашего кода на соответствие рекомендациям PEP 8.

Если вы хотите узнать больше о PEP 8, вы можете прочитатьfull documentation или посетитьpep8.org, который содержит ту же информацию, но был хорошо отформатирован. В этих документах вы найдете остальные рекомендации по PEP 8, не описанные в этом руководстве.