Сообщество приняло набор стилевых рекомендаций PEP8, который Гвидо ван Россум, создатель языка, предложил еще в 2001 году. Как применять и когда отступать — рассказываем в этой статье.
Что такое стандарты PEP8 для языка Python
С предсказуемым кодом приятно работать: сразу понятно, где импортированные модули, константа здесь или переменная и в каком блоке текущая строка. Для предсказуемости важны стиль и оформление, особенно в Python, который многое прощает разработчику.
Требования PEP8 по оформлению Python-кода
Единообразие, наглядность и информативность — это основа PEP8. Страница с текстом предложения постоянно дополняется, рекомендуем иногда перечитывать.
Чтобы оставаться востребованным специалистом, разработчику на любом языке нужно постоянно развиваться и совершенствовать навыки. А вот основы можно узнать и отработать на курсе Skypro «Python-разработчик». Программу составили практикующие разработчики, они же ведут уроки и объясняют всё простым и доступным языком. Так что освоить профессию на уровне уверенного новичка и найти работу можно через несколько месяцев с начала обучения.
Структура кода
В 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:
- Пишите полные предложения с заглавной буквы, если это не название.
- Ставьте два пробела после точки в комментариях, кроме последнего предложения.
- Пишите на английском, если читатели не знают ваш язык.
Блочные комментарии объясняют следующий за ними участок кода. Выравнивайте их на том же уровне и начинайте каждую строку с # и пробела. Параграфы в блочных комментариях разделяются строкой с одной #:
# 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()
Изучайте Python на онлайн-курсе от Skypro «Python-разработчик». Программа рассчитана на новичков без опыта программирования и технического образования. Курс проходит в формате записанных коротких видеолекций. Будет много проверочных заданий и мастер-классов. В конце каждой недели — живая встреча с экспертами в разработке для ответов на вопросы и разбора домашек.
Использование запятых
Кортеж из одного элемента отделяется запятой и берется в скобки для улучшения читаемости. Для систем контроля версий элементы в списке пишутся с новой строки и отделяются запятыми, если список будет расширяться. В остальных случаях запятые не ставятся:
# Правильно 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=’’
Не забудьте указать специальный комментарий, чтобы автоматические проверки игнорировали файл, если в проекте используются любые другие виды аннотаций:
# type: ignore
По умолчанию интерпретаторы Python должны игнорировать проверку типов и сохранять такое же поведение, как и без аннотаций. Линтеры и другой инструментарий — опциональны.
Другие рекомендации, на которые стоит обратить внимание:
- Используйте стандартную библиотеку, а не конкретную имплементацию (PyPy, CPython и т. д.).
- Реализуйте все операторы (__eq__, __ne__, __lt__, __le__, __gt__, __ge__) для сравнения элементов, не доверяйте внешнему коду в использовании только одного или нескольких.
- Определяйте функции ключевым словом def, а не знаком равенства: равенство оставляйте для лямбд.
- Наследуйте исключения от Exception вместо BaseException: BaseException зарезервировано для исключений, ловить которые — плохая идея.
- Сохраняйте стек вызовов при обработке цепочки исключений.
- Обрабатывайте конкретное исключение: слишком широкое условие (или пустой оператор except) поймает больше, чем нужно.
- Минимизируйте количество кода в try-блоке: в длинных условиях легче потеряться или проглотить ошибку.
- Очищайте локальные ресурсы с помощью with или try/finally.
- Вызывайте методы в менеджерах контекста явно. Исключение — резерв или возврат ресурса.
- Возвращайте единообразные значения: либо везде пустой return, либо везде результат или None.
- Проверяйте префиксы и суффиксы строк с помощью .startswith() и .endswith().
- Сравнивайте типы объектов через isinstance().
- Избегайте строковых литералов с пробельными символами в конце: некоторые редакторы и модули их обрежут.
Как проверить код на соответствие стандартам PEP8
Ручная проверка плохо подходит даже для небольших проектов: отнимает время, легко ошибиться. Используйте готовые инструменты:
- Среды разработки, например PyCharm.
- Pylint — для статического анализа и проверки стиля.
- Flake8 — для проверки стиля.
Pylint, Flake8 и многое другое лежит в разделе Python Code Quality Authority на гитхабе.
Когда можно проигнорировать соблюдение стандартов
Когда соблюдение стандартов ухудшает код. Помните: единообразный код понятнее и лучше читается. Например, PEP8 не применяется, если проект не доступен публично и уже использует другой стиль — или разрабатывался под старые версии Python. Для публичных библиотек PEP8 обязателен.
В проектах без единого стиля — договоритесь с командой и берите PEP8.
На курсе Skypro «Python-разработчик» можно научиться не только основам языка и разработки на нём, но и командной работе. А результаты практических заданий положить в портфолио, чтобы найти работу сразу после или даже во время обучения.
Коротко о главном
- Пишите единообразный код: его приятнее читать и легче воспринимать. PEP8 — стилевой стандарт сообщества.
- Выравнивайте блоки кода и отделяйте логические секции пустыми строками.
- Выбирайте понятные и однозначные имена для объектов.
- Добавляйте полезные комментарии. Обновляйте их, когда код меняется.
- Обрабатывайте исключения с узкими и краткими условиями.
- Берите автоматические инструменты проверки.
- Игнорируйте стандарты, если их соблюдение ухудшит код.
Добавить комментарий