Именование в Python по PEP 8: snake_case для переменных и функций

PEP 8 требует, чтобы имена функций и переменных были строчными, а слова разделялись подчёркиваниями там, где это нужно для читаемости. Это и есть snake_case: total_price, send_invoice(). Классы пишутся в CapWords (InvoiceSender), константы — заглавными буквами с подчёркиваниями (MAX_RETRIES), а модули получают короткие имена целиком строчными буквами. Этого хватает для большей части кода на Python, который вы будете писать.
Самые полезные подробности — в остальной части раздела PEP 8 об именовании: что значат подчёркивания в начале и в конце имени, как обращаться с аббревиатурами, каких одиночных букв избегать и когда нарушить правила — верное решение. Всё ниже сверено с самим PEP 8, а английские фразы в кавычках — собственные слова PEP 8 (перевод дан в скобках).
Соглашения PEP 8 об именовании: коротко
| Что вы называете | Стиль по PEP 8 | Пример |
|---|---|---|
| Модуль | Короткое имя целиком строчными; подчёркивания, если они помогают | billing.py, tax_rules.py |
| Пакет | Короткое имя целиком строчными; подчёркивания не рекомендуются | payments |
| Класс | CapWords | InvoiceSender |
| Исключение | CapWords, с окончанием Error, если это ошибка | PaymentDeclinedError |
| Функция, метод | snake_case | send_invoice() |
| Переменная, переменная экземпляра | snake_case | total_price |
| Первый аргумент метода | self или cls для методов класса | def from_settings(cls, settings) |
| Константа | Заглавные буквы с подчёркиваниями, обычно на уровне модуля | MAX_RETRIES |
| Переменная типа | Короткое имя в CapWords | T, AnyStr |
| Непубличное имя | Одно подчёркивание в начале | _rate_cache |
Вот большая часть таблицы в одном небольшом модуле:
# billing.py
MAX_RETRIES = 3
_rate_cache = {}
class PaymentDeclinedError(Exception):
pass
class InvoiceSender:
def __init__(self, smtp_host):
self.smtp_host = smtp_host
self._attempts = 0
def send_invoice(self, invoice_id):
self._attempts += 1
...
@classmethod
def from_settings(cls, settings):
return cls(settings["smtp_host"])Стоит знать ещё две более редкие строки. Переменные типа могут получать суффикс _co или _contra, обозначающий ковариантность или контравариантность, как в VT_co = TypeVar('VT_co', covariant=True). А глобальные переменные следуют правилам для функций; если модуль предназначен для использования через from module import *, PEP 8 рекомендует перечислить его публичные имена в __all__.
Зачем вообще нужен snake_case?
PEP 8 появился в июле 2001 года, а в числе его авторов указаны Guido van Rossum, Barry Warsaw и Alyssa Coghlan. Отправная точка — одно из наблюдений Guido: код читают гораздо чаще, чем пишут. Правила именования служат этой цели. Подчёркивания сохраняют видимыми границы слов даже в длинных именах (days_since_last_login), а разделение на значения в snake_case и классы в CapWords подсказывает, что за вещь перед вами, ещё до того, как вы посмотрите её определение. Для публичных API PEP 8 устанавливает и главный принцип: имена должны отражать то, как вещь используется, а не то, как она реализована.
Что значат подчёркивания
В Python нет ключевого слова private, поэтому эту работу по соглашению выполняют подчёркивания. PEP 8 выделяет четыре формы:
_single_leading: слабый сигнал «internal use» (для внутреннего использования).from module import *такие имена пропускает, но больше ничто не мешает ими пользоваться.single_trailing_: помогает избежать конфликта с ключевым словом.class_лучше, чемclss, хотя PEP 8 замечает, что синоним может оказаться ещё лучше.__double_leading: внутри класса запускает искажение имён (name mangling). PEP 8 советует применять его только для того, чтобы избежать конфликтов с атрибутами в подклассах, и признаёт, что некоторым оно не нравится.__double_leading_and_trailing__: имена «magic» (магические), такие как__init__и__file__. PEP 8 говорит никогда не придумывать их самим; используйте только документированные.
Искажение имён удивляет тех, кто принимает его за приватность. Это переименование, а не замок:
class Account:
def __init__(self):
self.__pin = "1234"
acct = Account()
acct.__pin # AttributeError
acct._Account__pin # "1234": the mangled name still worksКонстанты — это соглашение, а не правило
Запись имени заглавными буквами не мешает его переприсвоить; Python без возражений выполнит MAX_RETRIES = 4. Если вы хотите, чтобы это проверял инструмент, пометьте имя аннотацией typing.Final:
from typing import Final
MAX_RETRIES: Final = 3
MAX_RETRIES = 4 # still runs, but mypy reports:
# Cannot assign to final name "MAX_RETRIES"Члены перечислений (enum) — ещё одно место, где встречаются заглавные буквы. Руководство enum HOWTO в документации Python настоятельно рекомендует имена членов в UPPER_CASE: отчасти потому, что перечисления представляют константы, отчасти чтобы избежать конфликтов с именами методов; пример — class Color(Enum) с членами RED и GREEN.
Аббревиатуры, одиночные буквы и другие особые случаи
Аббревиатуры в именах классов
PEP 8 говорит писать в CapWords каждую букву аббревиатуры заглавной, поэтому HTTPServerError лучше, чем HttpServerError. Стандартная библиотека следует этому в таких местах, как http.server.HTTPServer и json.JSONDecodeError. В snake_case аббревиатуры просто пишутся строчными: parse_json, http_status.
Это важно, если вы переименовываете с помощью инструмента. Наш конвертер регистра превращает processOrder в process_order, а HTTPServerError — в http_server_error, и для snake_case это в точности то, что нужно. Но в PascalCase он пишет аббревиатуры как слова, так что из HTTP server error получается HttpServerError, и заглавные буквы вам придётся исправить вручную, чтобы привести имя в соответствие с PEP 8.
Буквы, которых стоит избегать
Никогда не используйте l (строчная L), O (заглавная o) и I (заглавная i) как односимвольные имена. В некоторых шрифтах их невозможно отличить от 1 и 0.
mixedCase
Имена функций в camelCase допустимы только там, где этот стиль уже преобладает, ради обратной совместимости. Собственный пример PEP 8 — модуль threading.
Почему стандартная библиотека нарушает собственные правила
PEP 8 признаёт, что именование в библиотеке Python — «a bit of a mess» (довольно беспорядочное). Вам встретятся logging.getLogger() и assertEqual() из unittest в mixedCase, а также классы со строчной буквы вроде datetime.datetime. Встроенные типы вроде list и dict написаны строчными намеренно: PEP 8 описывает отдельное соглашение для встроенных объектов, где CapWords используется только для имён исключений и встроенных констант.
Два положения из PEP 8 объясняют, почему эти имена в основном остаются как есть. Во-первых, если у существующей библиотеки другой стиль, предпочтение отдаётся внутреннему единообразию. Во-вторых, раздел под названием «A Foolish Consistency is the Hobgoblin of Little Minds» (глупая последовательность — пугало для мелких умов): единообразие с PEP 8 важно, единообразие внутри проекта важнее, а внутри модуля или функции — важнее всего. Не ломайте обратную совместимость только ради соблюдения правил. Поэтому тестовый класс unittest по-прежнему определяет setUp(): фреймворк вызывает именно это имя.
Проверяйте имена автоматически с помощью Ruff или pep8-naming
Просматривать имена глазами не нужно. Их проверяет плагин flake8 pep8-naming, а Ruff реализует те же проверки в виде правил N. Возьмём такой файл:
maxRetries = 3
class order_processor:
def processOrder(self, orderId):
totalPrice = 0
return totalPrice
class InvalidOrder(Exception):
passRuff отмечает в нём каждое имя:
$ ruff check --select N --output-format concise orders.py
orders.py:1:1: N816 Variable `maxRetries` in global scope should not be mixedCase
orders.py:4:7: N801 Class name `order_processor` should use CapWords convention
orders.py:5:9: N802 Function name `processOrder` should be lowercase
orders.py:5:28: N803 Argument name `orderId` should be lowercase
orders.py:6:9: N806 Variable `totalPrice` in function should be lowercase
orders.py:10:7: N818 Exception name `InvalidOrder` should be named with an Error suffix
Found 6 errors.Чтобы включить эти правила для всего проекта, добавьте их в pyproject.toml:
[tool.ruff.lint]
extend-select = ["N"]Когда вы переименовываете один идентификатор во вставленном файле, наш инструмент «Найти и заменить» показывает, сколько совпадений он изменил: это быстрая проверка на здравый смысл, прежде чем вставлять результат обратно. Для всей кодовой базы лучше используйте рефакторинг переименования в редакторе, чтобы ссылки в других файлах изменились вслед за именем.
Чек-лист по именованию в PEP 8
- snake_case — для функций, методов, переменных и аргументов.
- CapWords — для классов, с аббревиатурами заглавными буквами и суффиксом
Errorу исключений. - Заглавные буквы с подчёркиваниями — для констант уровня модуля, плюс
Final, если вы хотите, чтобы их проверял инструмент. - Короткие имена модулей строчными; в именах пакетов избегайте подчёркиваний.
- Одно подчёркивание в начале — для внутренних имён; двойное — только чтобы избежать конфликтов в подклассах.
- Если существующая библиотека использует другой стиль, подстраивайтесь под библиотеку.
Переходите с языка на язык? Наша шпаргалка для разработчиков сопоставляет правила Python с JavaScript, Java, Go, Rust и другими языками.


