Баннер мобильный (3) Пройти тест

Руководство по написанию кода PEP 8: что это такое и как его применять

Делаем все по правилам

Разбор

4 декабря 2025

Поделиться

Скопировано
Руководство по написанию кода PEP 8: что это такое и как его применять

Содержание

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

    Что такое PEP 8 и зачем он нужен

    PEP 8, или Python Enhancement Proposal (предложение по улучшению Python) 8  — это официальный стандарт оформления кода на языке Python. Его разработал Гвидо ван Россум, основатель языка, в сотрудничестве с другими специалистами. Стандарт стал де-факто руководством для всех разработчиков, работающих с Python. Он обеспечивает единообразие и читаемость кода. PEP 8 включает правила использования отступов, именования переменных, функций и классов, а также форматирование строк и расстановку пробелов. 

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

    Соблюдать рекомендации PEP 8 особенно важно при работе в команде, так как единый стиль кодирования упрощает совместную работу над проектами и облегчает их поддержку. Многие современные инструменты разработки и интегрированные среды разработки (IDE) включают функции автоматической проверки соответствия кода стандартам PEP 8, что делает процесс соблюдения этих рекомендаций более удобным и эффективным для разработчиков.

    Рассмотрим несколько основных правил из стандарта PEP 8 на примерах.

    Отступы в PEP 8

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

    if x == 10:
        print("x равно 10")

    А вот такое написание будет считаться неправильным:

    if x == 10:
           print("x равно 10")

    Здесь целых три лишних пробела.

    Длина строки 

    Для лучшего восприятия кода длина строки не должна быть больше 79 символов. Длинные строки следует разбивать на более короткие при помощи обратного слеша (\). Допустим, у нас есть такая строка:

    long_str = "Python — это высокоуровневый, интерпретируемый язык программирования, известный своей простотой, читабельностью и универсальностью."

    Разделим ее на две части:

    long_str = "Python — это высокоуровневый, интерпретируемый язык программирования, " \
          "известный своей простотой, читабельностью и универсальностью."

    Пробелы в PEP 8

    Между операторами и операндами нужно использовать один пробел. Не следует вставлять пробелы между скобками и находящимися внутри операндами. Пример правильного использования пробелов:

    a = 12 + 3
    b = (1 + 2) * 10

    Неправильное использование пробелов:

    a=12+3
    b = ( 1 + 2 ) * 10

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

    my_function(argument=15)

    Неправильно:

    my_function(argument = 15)

    Имена переменных и функций

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

    age = 48
    first_name = "George"

    Здесь сразу видно, что в переменной age хранится возраст, а в переменной first_name — имя. Тот же самый пример, но без учета правил:

    a = 48
    b = "George"

    В таком варианте именования уже непонятно, что за значения присваиваются переменным. Это правило касается и имен функций. 

    Правильный вариант:

    def calculate_length(text):
        return len(text)

    Неправильный вариант:

    def calc(text):
        return len(text)

    В первом случае имя функции нам прямо сообщает, что выполняется вычисление длины (по аргументу text понятно длина чего именно вычисляется), а во втором случае имя calc нам ни о чем таком не говорит.

    Комментарии

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

    # Получаем название ОС
    os_name = platform.system()

    А вот так будет неправильно:

    os_name = platform.system()  # Получаем название операционной системы

    Импорты в PEP 8

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

    import datetime
    import os
    
    from math import pow
    
    import requests

    Неправильные:

    import requests, os, datetime
    
    from math import *

    Классы и функции

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

    class FirstClass:
        pass
    
    
    class SecondClass:
        pass
    
    
    def my_function():
        return None

    А внутри классов рекомендуется разделять функции одной пустой строкой:

    class MyClass:
        def first_function(self):
            return None
    
        def second_function(self):
            return None

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

    def on_calculate():
        if calc_entry.index("end") == 0:
            result_label.config(text="Введите выражение!")
            return
    
        expression = calc_entry.get()
    
        try:
            result = eval(expression)
        except Exception as ex:
            result_label.config(text=ex)
            return
    
        result_label.config(text=result)

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

    Документирование в PEP 8

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

    def calculate_length(text):
        """
        Эта функция вычисляет длину строки.
    
        Параметры:
            text (string): Строка, длину которой нужно вычислить.
    
        Возвращает:
            int: Длина строки.
        """
        return len(text)

    Строки документации вместе с комментариями делают код более понятным и в нем быстрее можно разобраться.

    Инструменты для приведения кода в соответствие правилам PEP 8

    Есть удобные инструменты, с помощью которых можно быстро проверить свой код на соответствие принципам PEP 8. Ниже приводим список наиболее популярных:

    • Pylint — этот линтер предназначен для статического анализа кода на языке Python. Помогает найти ошибки, а также поддерживает рекомендации PEP 8.
    • Pycodestyle — один из старейших анализаторов кода. До 2016-го года назывался просто pep8. Создан специально для проверки кода на соответствие соглашениям PEP 8.
    • Flake8 — комбинированный инструмент, объединяющий в себе несколько других. Он умеет не только проверять стилистику PEP 8, но также способен проверять код на наличие различных ошибок.
    • Black — это инструмент для автоматического форматирования кода. Это значит, что он самостоятельно способен исправлять найденные ошибки. Поддерживает более строгие стандарты основанные на PEP 8. 
    • Autopep8 — еще один автоматический форматтер.
    • YAPF — тоже автоформаттер, но может работать не только со стандартами PEP 8.

    Посмотрим на работу этих инструментов на примере Pycodestyle и Autopep8. Сначала их нужно установить. Так как Autopep8 зависит от Pycodestyle, то достаточно установить только Autopep8, а Pycodestyle установится автоматически. Открываем консоль и пишем там такую команду:

    pip install autopep8

    Теперь можно приступать к работе. Возьмем такой исходник:

    def calculate_length(text):
           return len(text)
    
    print(calculate_length("abcdefghij"))

    Сохраним его под именем examples.py в любом удобном месте. Чтобы проверить этот код при помощи Pycodestyle надо сначала открыть консоль в папке с исходником и скомандовать:

    pycodestyle examples.py

    Вывод в консоли будет такой:

    examples.py:3:8: E111 indentation is not a multiple of 4
    examples.py:3:8: E117 over-indented
    examples.py:5:1: E305 expected 2 blank lines after class or function definition, found 1

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

    autopep8 --in-place --aggressive --aggressive examples.py

    Ответа мы никакого не получим, а вот наш исходник автоматически исправлен:

    def calculate_length(text):
        return len(text)
    
    
    print(calculate_length("abcdefghij"))

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

    Задача для практики

    Ниже приведем исходный код консольного генератора паролей. В нем есть несоответствия стандартам PEP 8. Найдите и устраните их. Код генератора:

    import secrets, string
    
    
    def is_valid_password(password):
        """Проверяет, содержит ли пароль все необходимые символы"""
        has_lower = any(c.islower() for c in password)
        has_upper = any(c.isupper() for c in password)
        has_digit = any(c.isdigit() for c in password)
        has_punct = sum(c in string.punctuation for c in password)<=3
    
        return has_lower and has_upper and has_digit and has_punct
    
    
    def generate_password(length=12):
        # Наборы символов
        all_chars = string.ascii_letters + string.digits + string.punctuation
    
        while True:
            # Генерируем случайный пароль
            password = [secrets.choice(all_chars) for _ in range(length)]
    
            # Проверяем валидность
            if is_valid_password(password):
                   return ''.join(password)
    
    print(generate_password())
    Решение

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

    examples.py:1:15: E401 multiple imports on one line
    examples.py:9:63: E225 missing whitespace around operator
    examples.py:24:16: E111 indentation is not a multiple of 4
    examples.py:24:16: E117 over-indented
    examples.py:26:1: E305 expected 2 blank lines after class or function definition, found 1

    Видим, что у нас проблемы с импортами (модули перечислены через запятую), отсутствуют пробелы до и после оператора (строка 9), чрезмерный отступ на 24-й строке и не хватает двух пустых строк на 26-й строке. Исправить это можно с помощью Autopep8. Применив этот инструмент, получим исправленный исходник:

    import secrets
    import string
    
    
    def is_valid_password(password):
        """Проверяет, содержит ли пароль все необходимые символы"""
        has_lower = any(c.islower() for c in password)
        has_upper = any(c.isupper() for c in password)
        has_digit = any(c.isdigit() for c in password)
        has_punct = sum(c in string.punctuation for c in password) <= 3
    
        return has_lower and has_upper and has_digit and has_punct
    
    
    def generate_password(length=12):
        # Наборы символов
        all_chars = string.ascii_letters + string.digits + string.punctuation
    
        while True:
            # Генерируем случайный пароль
            password = [secrets.choice(all_chars) for _ in range(length)]
    
            # Проверяем валидность
            if is_valid_password(password):
                return ''.join(password)
    
    
    print(generate_password())

    (Конец решения)

    Разбор

    Поделиться

    Скопировано
    0 комментариев
    Комментарии