pep8. Коротко о главном
Итак, как уже говорилось, PEP8 это документ, описывающий общепринятый стиль написания кода на языке Python. Далее представлен короткий вариант PEP8, который состоит из 25 правил.
- На каждый уровень отступа используйте по 4 пробела. Табуляция используется лишь для поддержки старого кода, где они уже используются.
- Длину строки рекомендуется ограничить 79 символами. Предпочтительный способ переноса длинных строк — использование подразумевающегося продолжения строки между обычными, квадратными и фигурными скобками. Так же для переноса разрешается использовать обратный слэш («\»).
- Функции верхнего уровня и определения классов отделяются двумя пустыми строками. Определения методов внутри класса разделяются одной пустой строкой. Дополнительные пустые строки используются для логического разделения.
- Кодировка в Python 2 должна быть ASCII. А в Python 3 — UTF-8.
- Для каждого импорта — отдельная строка. Порядок расположения — стандартные библиотеки, сторонние библиотеки, локальные модули приложения. Импорты всегда помещаются в начале файла, сразу после комментариев к модулю и строк документации, и перед объявлением констант. Используйте пустую строку для отделения групп импортов.
- Избегайте лишних пробелов внутри круглых, квадратных или фигурных скобок; перед запятой, точкой с запятой или двоеточием. Сразу перед открывающей скобкой, после которой начинается список аргументов при вызове функции. Не используйте больше одного пробела вокруг любого оператора для того, чтобы выровнять его с другим.
- Используйте одиночный пробел с каждой стороны у операторы присваивания(=, +=, -=), операторов сравнения (==, , !=, <>, =, in, not in, is, is not) и логических операторов (and, or, not). Не используйте пробелы вокруг знака =, если он используется для обозначения именованного аргумента или значения параметров по умолчанию.
- Комментарии, которые противоречат коду, хуже, чем их отсутствие. Всегда исправляйте комментарии при обновлении кода. По возможности пишите комментарии на английском языке. Каждая строчка такого блока должна начинаться с символа # и одного пробела после него.
- Пишите документацию для всех public модулей, функций, классов, методов.
- Никогда не используйте символы l (маленькая латинская буква «L»), O (заглавная латинская буква «o») или I (заглавная латинская буква «i») в качестве имен.
- Модули должны иметь короткие имена, состоящие из маленьких букв.
- Имена классов должны обычно следовать соглашению CapitalizedWords (слова с заглавными буквами).
- Имена функций должны состоять из маленьких букв, а слова разделяться символами подчеркивания(lower_case_with_underscores).
- Для имен методов и переменных экземпляров классов используйте тот же стиль, что и для имен функций.
- Всегда используйте self в качестве первого аргумента метода экземпляра объекта. Всегда используйте cls в качестве первого аргумента метода класса.
- Обязательно решите, каким должен быть метод класса или экземпляра класса — public или не-public. Если вы сомневаетесь, выберите не-public.
- Код должен быть написан так, чтобы не зависеть от разных реализаций языка.
- Сравнения с None должны обязательно выполняться с использованием операторов is или is not, а не с помощью операторов сравнения.
- Наследуйте свой класс исключения от Exception. Перехватывайте конкретные ошибки вместо простого выражения except.
- Всегда используйте выражение def, а не присваивание лямбда-выражения к имени
- Постарайтесь заключать в каждую конструкцию try. except минимум кода, чтобы легче отлавливать ошибки.
- Используйте строковые методы вместо модуля string. Используйте ».startswith() и ».endswith() вместо вырезки из строк для проверки префиксов и суффиксов.
- Сравнение типов объектов нужно делать с помощью isinstance().
- Для последовательностей (строк, списков, кортежей) используйте тот факт, что пустая последовательность есть false.
- Не сравнивайте логические типы с True и False с помощью == .
Опубликованно: 16-11-2015
Что такое pep8 в python
PEP8 можно определить, как документ, описывающий общепринятый стиль написания кода на языке Python. Python Enhanced Proposal (PEP) — переводится, как заявки по улучшению языка Python.
Помимо PEP8, так же имеются и другие документы под индексами о которых можно прочитать в PEP0. Но наибольшего внимания заслуживает именно PEP8, а так же PEP7 (В нем описывается какого стиля следует придерживаться при написании кода на C в реализации языка python)
На этой странице представлено полное описание PEP8 на русском языке. Так же вы можете ознакомится с коротким описанием PEP8.
1. Внешний вид кода
Отступы
Используйте 4 пробела на каждый уровень отступа.
На каждый уровень отсупа используйте 4 пробела. Для действительно старого кода, который вы не хотите трогать, можите продолжать использовать 8 пробелов.
Табуляция или пробелы?
Пробелы — наиболее предпочтительный метод отступов.
Табуляция может быть использоваться только для поддержки кода, в котором были использованы отступы с помощью табуляции.
В Python 3 запрещается смешивание табуляции и пробелов в отступах.
В Python 2 табуляция преобразовыватеся в пробелы.
Интерпретатор Python 2 выдает предупреждения (warnings) при использовании смешанного стиля в отступах при использовании параметра -t. При использовании прараметра -tt, интерпретатор выдаст ошибки (errors) в этих местах. Использование этих параметров очень рекомендуется.
В новых проектах для отступов настоятельно рекомендется использовать пробелы. В этом вам могут помочь многие редакторы
Максимальная длина строки
Длину строки рекомендуется ограничить 79 символами
Для более длинных блоков текста с меньшими структурными ограничениями, таким как строки документации или комментарии, длину строки следует ограничить 72 символами.
Сейчас все еще существует устройства, где длина строки ограничена 80 символам. Автоматический перенос строк на таких устройствах нарушит форматирование, и код будет труднее понять. Так же, ограничив ширину окна 80 символами, мы сможем расположить несколько окон рядом друг с другом.
Предпочтительный способ переноса длинных строк — использование подразумевающегося продолжения строки между обычными, квадратными и фигурными скобками. Если необходимо — можно добавить еще одну пару скобок вокруг выражения, но лучше использовать обратный слэш («\»).
with open('/path/to/some/file/you/want/to/read') as file_1, \ open('/path/to/some/file/being/written', 'w') as file_2: file_2.write(file_1.read())
Другой вариант — инструкция assert.
Постарайтесь сделать правильные отступы для перенесённой строки. Предпочтительнее ставить перенос после бинарного оператора, а не перед ним.
class Rectangle(Blob): def __init__(self, width, height, color='black', emphasis=None, highlight=0): if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100): raise ValueError("sorry, you lose") if width == 0 and height == 0 and (color == 'red' or emphasis is None): raise ValueError("I don't think so -- values are %s, %s" % (width, height)) Blob.__init__(self, width, height, color, emphasis, highlight)
Пустые строки
Функции верхнего уровня и определения классов отделяются двумя пустыми строками.
Определения методов внутри класса разделяются одной пустой строкой.
Дополнительные отступы пустыми строками могут быть использованы для выделения группы логически связанных функций. Пустые строки могут быть пропущены, между несколькими выражениями, записанными в одну строку, например, «заглушки» функций.
Используйте пустые строки в коде функций, чтобы указать логические разделы.
Python расценивает символ Сontrol+L как незначащий (whitespace). Вы можете использовать его, так как многие редакторы обрабатывают его как разрыв страницы — таким образом логические части в файле будут на разных страницах.
Кодировка исходного файла
Кодировка Python 3 должна быть UTF-8 (ASCII в Python 2).
Файлы в ASCII (Python 2) или UTF-8 (Python 3) не должны иметь объявления кодировки.
В стандартной библиотеке, нестандартные кодировки должны использоваться только для тестирования, либо если комментарий или строка документации требует упомянуть имя автора, содержащего не ASCII символы; в остальных случаях использование \x, \u, \U или \N — наиболее предпочтительный способ включить не ASCII символы в строковых литералах.
Начиная с версии python 3.0 в стандартной библиотеке действует следующее соглашение: все идентификаторы обязаны содержать только ASCII символы, и означать английские слова везде, где это возможно. Кроме того, строки и комментарии тоже должны содержать лишь ASCII символы. Исключения составляют:
1) test case, тестирующий не-ASCII особенности программы;
2) Bмена авторов. Авторы, чьи имена основаны не на латинском алфавите, должны транслитерировать свои имена в латиницу.
Проектам с кодом открытым для широкой аудитории также рекомендуется использовать это соглашение.
Импорты
- Для каждого импорта — отдельная строка. Правильно:
import os import datetime
Неправильно:
import os, datetime
В то же время, можно писать так:
from subprocess import Popen, PIPE
- импорты из стандартной библиотеки
- импорты сторонних библиотек
- импорты модулей текущего проекта
Между каждой группой импортов вставляйте пустую строку.
Указывайте спецификации __all__ после импортов.
from myclass import MyClass from foo.bar.yourclass import YourClass
Если такое написание вызывает конфликт имен, тогда пишите:
import myclass import foo.bar.yourclass
Пробелы в выражениях и инструкциях
Следует избегать использования пробелов в следующих ситуациях:
- Внутри круглых, квадратных или фигурных скобок. Правильно:
animals(tiger[2 ], : 6>)
Неправильно:
animals ( tiger [ 1 ], eagle : 2 > )
if x == y:
if x == y :
tiger(1)
Неправильно:
tiger (1)
dict['key'] = list[index]
Неправильно:
dict ['key'] = list [index]
x = 1 y = 2 long_variable = 3
Неправильно:
x = 1 y = 2 long_variable = 3
Другие рекомендации
- Всегда окружайте следующие бинарные операторы одним пробелом с каждой стороны: операторы присваивания (=, +=, -= и другие), операторы сравнения (==, , !=, <>, =, in, not in, is, is not), логические операторы (and, or, not).
- Если используются операторы с разными приоритетами, попробуйте добавить пробелы вокруг операторов с самым низким приоритетом для того, чтобы сразу визуально отличить очередность выполнения. Используйте свои собственные суждения, но никогда не используйте более одного пробела, а так же всегда используйте одинаковое количество пробелов по обе стороны бинарного оператора. Правильно:
i = i + 1 submitted += 1 x = x*2 - 1 hypot2 = x*x + y*y c = (a+b) * (a-b)
Неправильно:
i=i+1 submitted +=1 x = x * 2 - 1 hypot2 = x * x + y * y c = (a + b) * (a - b)
def complex(real, imag=0.0): return magic(r=real, i=imag)
Неправильно:
def complex(real, imag = 0.0): return magic(r = real, i = imag)
if foo == 'blah': do_blah_thing() do_one() do_two() do_three()
Неправильно:
if foo == 'blah': do_blah_thing() do_one(); do_two(); do_three()
if foo == 'blah': do_blah_thing() for x in lst: total += x while t 10: t = delay()
Точно неправильно:
if foo == 'blah': do_blah_thing() else: do_non_blah_thing() try: something() finally: cleanup() do_one(); do_two(); do_three(long, argument, list, like, this) if foo == 'blah': one(); two(); three()
Комментарии
Комментарии, которые противоречат коду, хуже, их отсутсвие. Всегда исправляйте комментарии, когда меняете код!
Комментарии должны представлять собой законченными предложениями. Если комментарий — фраза или предложение, первое слово должно быть написано с большой буквы, если только это не имя переменной, которая начинается с маленькой буквы (никогда не изменяйте регистр переменной!).
Если комментарий короткий, можно не ставить точку в конце предложения. Блок комментариев обычно состоит из одного или более абзацев, составленных из полноценных предложений, поэтому каждое предложение должно оканчиваться точкой.
Ставьте два пробела после точки в конце предложения.
Если вы пишете по-английски, не забывайте о книге “Elements of style” Странка и Уайта. Эта книга является эталонным руководством по правильному написанию текстов на английском языке.
Программистам, которые не говорят на английском языке следует писать комментарии на английском. За исключением случаев, когда Вы на 126% уверены, что Ваш код никогда не будут читать люди не знающие вашего родного языка.
Блоки комментариев
Блок комментариев обычно объясняет код (весь, или только некоторую часть), идущий после блока, и должен иметь тот же отступ, что и сам код.
Каждая строчка такого блока должна начинаться с символа # и одного пробела после него.
Абзацы внутри блока комментариев разделяются строкой, состоящей только из одного символа #.
«Встрочные» комментарии
Старайтесь реже использовать подобные комментарии.
Такой комментарий находится в той же строке, что и инструкция. «Встрочные» комментарии должны отделяться как минимум двумя пробелами от самой инструкции. И должны начинаться с символа # и одного пробела.
Если комментарии объясняют очевидное — они не нужны, т.к. только отвлекают от чтения кода
Пример как писать не нужно:
x = x + 1 # Increment x
Строки документации
- Пишите документацию для всех public модулей, функций, классов, методов. Для не-public методов cтроки документации необязательны, но лучше описать, что делает метод. Комментарий нужно писать после строки с def.
- PEP 257 объясняет, как правильно писать документацию. Очень важно, чтобы закрывающие кавычки стояли на отдельной строке. А еще лучше, если перед ними будет ещё и пустая строка.
"""Return a foobang Optional plotz says to frobnicate the bizbaz first. """
Контроль версий
Если вам нужно использовать Subversion, CVS или RCS в ваших исходных кодах, делайте вот так:
__version__ = "$Revision: 1a40d4eaa00b $" # $Source$
Вставляйте эти строки после документации модуля перед любым другим кодом и отделяйте их пустыми строками по одной до и после.
Соглашения по именованию
Соглашения по именованию переменных в python немного туманны, поэтому их список никогда не будет полным — тем не менее, ниже мы приводим список рекомендаций, действующих на данный момент. Новые модули и пакеты должны быть написаны согласно этим стандартам, но если в какой-либо уже существующей библиотеке эти правила нарушаются, предпочтительнее писать в едином с ней стиле.
Главный принцип
Имена, которые видны пользователю как часть общественного API должны следовать конвенциям, которые отражают использование, а не реализацию.
Описание: Стили имен
Существует много разных стилей. Поможем вам распознать, какой стиль именования используется, независимо от того, для чего он используется.
Обычно различают следующие стили:
- b (одиночная маленькая буква)
- B (одиночная заглавная буква)
- lowercase (слово в нижнем регистре)
- lower_case_with_underscores (слова из маленьких букв с подчеркиваниями)
- UPPERCASE (заглавные буквы)
- UPPERCASE_WITH_UNDERSCORES (слова из заглавных букв с подчеркиваниями)
- CapitalizedWords (слова с заглавными буквами, или CapWords, или CamelCase). Замечание: когда вы используете аббревиатуры в таком стиле, пишите все буквы аббревиатуры заглавными — HTTPServerError лучше, чем HttpServerError.
- mixedCase (отличается от CapitalizedWords тем, что первое слово начинается с маленькой буквы)
- Capitalized_Words_With_Underscores (слова с заглавными буквами и подчеркиваниями. Выглядит уродливо!)
В дополнение к этому, используются следующие специальные формы записи имен с добавлением символа подчеркивания в начало или конец имени:
- _single_leading_underscore: слабый индикатор того, что имя используется для внутренних нужд. Например, from M import * не будет импортировать объекты, чьи имена начинаются с символа подчеркивания.
- single_trailing_underscore_: используется по соглашению для избежания конфликтов с ключевыми словами языка python, например:
Tkinter.Toplevel(master, class_='ClassName')
Предписания: соглашения по именованию
Имена, которых следует избегать
Никогда не используйте символы l (маленькая латинская буква «L»), O (заглавная латинская буква «o») или I (заглавная латинская буква «i») как однобуквенные идентификаторы.
В некоторых шрифтах эти символы неотличимы от цифры один и нуля. Если очень нужно l, пишите вместо неё заглавную L.
Имена модулей и пакетов
Модули должны иметь короткие имена, состоящие из маленьких букв. Можно использовать символы подчеркивания, если это улучшает читабельность. То же самое относится и к именам пакетов, однако в именах пакетов не рекомендуется использовать символ подчёркивания.
Так как имена модулей отображаются в имена файлов, а некоторые файловые системы являются нечувствительными к регистру символов и обрезают длинные имена, очень важно использовать достаточно короткие имена модулей — это не проблема в Unix, но, возможно, код окажется непереносимым в старые версии Windows, Mac, или DOS.
Когда модуль расширения, написанный на С или C++, имеет сопутствующий python-модуль (содержащий интерфейс высокого уровня), С/С++ модуль начинается с символа подчеркивания, например, _socket.
Имена классов
Имена классов должны обычно следовать соглашению CapitalizedWords .
Вместо этого могут использоваться соглашения для именования функций, если интерфейс документирован и используется в основном как функции.
Обратите внимание, что существуют отдельные соглашения о встроенных именах: большинство встроенных имен — одно слово (либо два слитно написанных слова), а соглашение CapitalizedWords используется только для именования исключений и встроенных констант.
Имена исключений
Так как исключения являются классами, к исключениями применяется стиль именования классов. Однако вы можете добавить Error в конце имени (если, конечно, исключение действительно является ошибкой).
Имена глобальных переменных
Будем надеяться, что глобальные переменные используются только внутри одного модуля. Руководствуйтесь теми же соглашениями, что и для имен функций.
Добавляйте в модули, которые написаны так, чтобы их использовали с помощью from M import *, механизм __all__, чтобы предотвратить экспортирование глобальных переменных. Или же, используйте старое соглашение, добавляя перед именами таких глобальных переменных один символ подчеркивания (которым вы можете обозначить те глобальные переменные, которые используются только внутри модуля).
Имена функций
Имена функций должны состоять из маленьких букв, а слова разделяться символами подчеркивания — это необходимо, чтобы улучшить читабельность.
Стиль mixedCase допускается в тех местах, где уже преобладает такой стиль, для сохранения обратной совместимости.
Аргументы функций и методов
Всегда используйте self в качестве первого аргумента метода экземпляра объекта.
Всегда используйте cls в качестве первого аргумента метода класса.
Если имя аргумента конфликтует с зарезервированным ключевым словом python, обычно лучше добавить в конец имени символ подчеркивания, чем исказить написание слова или использовать аббревиатуру. Таким образом, class_ лучше, чем clss. (Возможно, хорошим вариантом будет подобрать синоним).
Имена методов и переменных экземпляров классов
Используйте тот же стиль, что и для имен функций: имена должны состоять из маленьких букв, а слова разделяться символами подчеркивания.
Используйте один символ подчёркивания перед именем для непубличных методов и атрибутов.
Чтобы избежать конфликтов имен с подклассами, используйте два ведущих подчеркивания.
Константы
Константы обычно объявляются на уровне модуля и записываются только заглавными буквами, а слова разделяются символами подчеркивания. Например: MAX_OVERFLOW, TOTAL.
Проектирование наследования
Обязательно решите, каким должен быть метод класса или экземпляра класса (далее — атрибут) — public или не-public. Если вы сомневаетесь, выберите не-public атрибут. Потом будет проще сделать его public.
Public атрибуты — это те, которые будут использовать другие программисты, и вы должны быть уверены в обратной совместимости.
Мы не используем термин «private атрибут», потому что на самом деле в python таких не бывает.
Теперь сформулируем рекомендации:
- Открытые атрибуты не должны иметь в начале имени символа подчеркивания.
- Если имя открытого атрибута конфликтует с ключевым словом языка, добавьте в конец имени один символ подчеркивания. Это более предпочтительно, чем аббревиатура или искажение написания (однако, у этого правила есть исключение — аргумента, который означает класс, и особенно первый аргумент метода класса (class method) должен иметь имя cls).
- Назовите простые публичные атрибуты понятными именами и не пишите сложные методы доступа и изменения. Помните, что в python очень легко добавить их потом, если потребуется. В этом случае используйте свойства (properties), чтобы скрыть функциональную реализацию за синтаксисом доступа к атрибутам.
- Если вы планируете класс таким образом, чтобы от него наследовались другие классы, но не хотите, чтобы подклассы унаследовали некоторые атрибуты, добавьте в имена два символа подчеркивания в начало, и ни одного — в конец. Механизм изменения имен в python сработает так, что имя класса добавится к имени такого атрибута, что позволит избежать конфликта имен с атрибутами подклассов.
Общие рекомендации
- Код должен быть написан так, чтобы не зависеть от разных реализаций языка (PyPy, Jython, IronPython, Pyrex, Psyco и пр.). Например, не полагайтесь на эффективную реализацию в CPython конкатенации строк в выражениях типа a+=b или a=a+b. Такие инструкции выполняются значительно медленнее в Jython. В критичных к времени выполнения частях программы используйте ».join() — таким образом склеивание строк будет выполнено за линейное время независимо от реализации python.
- Сравнения с None должны обязательно выполняться с использованием операторов is или is not, а не с помощью операторов сравнения.
- При реализации методов сравнения, лучше всего реализовать все 6 операций сравнения (__eq__, __ne__, __lt__, __le__, __gt__, __ge__), чем полагаться на то, что другие программисты будут использовать только конкретный вид сравнения. Для минимизации усилий можно воспользоваться декоратором functools.total_ordering() для реализации недостающих методов. PEP 207 указывает, что интерпретатор может поменять y > х на х < y, y >= х на х . Однако, лучше всего осуществить все шесть операций, чтобы не возникало путаницы в других местах.
- Всегда используйте выражение def, а не присваивание лямбда-выражения к имени. Правильно:
def f(x): return 2*x
Неправильно:
f = lambda x: 2*x
try: import platform_specific_module except ImportError: platform_specific_module = None
- Если обработчик выводит пользователю всё о случившейся ошибке;
- Если нужно выполнить некоторый код после перехвата исключения, а потом вновь «бросить» его для обработки где-то в другом месте. Обычно же лучше пользоваться конструкцией «try. finally».
try: process_data() except Exception as exc: raise DataProcessingFailedError(str(exc))
try: value = collection[key] except KeyError: return key_not_found(key) else: return handle_value(value)
Неправильно:
try: # Здесь много действий! return handle_value(collection[key]) except KeyError: # Здесь также перехватится KeyError, который может быть сгенерирован handle_value() return key_not_found(key)
with conn.begin_transaction(): do_stuff_in_transaction(conn)
Неправильно:
with conn: do_stuff_in_transaction(conn)
if foo.startswith('bar'):
Неправильно:
if foo[:3] == 'bar':
if isinstance(obj, int):
Неправильно:
if type(obj) is type(1):
Когда вы проверяете, является ли объект строкой, обратите внимание на то, что строка может быть unicode-строкой. В python 2 у str и unicode есть общий базовый класс, поэтому вы можете написать:
if isinstance(obj, basestring):
if not seq: if seq:
Неправильно:
if len(seq) if not len(seq)
if greeting:
Неправильно:
if greeting == True:
PEP8: руководство по написанию чистого и читаемого кода на Python
Когда дело доходит до написания крупных проектов или поддержки существующего кода, становится очень важным следовать определенным стандартам кодирования, чтобы обеспечить читаемость, понятность и поддерживаемость кода.
Один из таких стандартов — PEP8, который устанавливает рекомендации по стилю и форматированию кода на языке Python.
Введение
PEP8 — это документ, описывающий стандарты, которые разработчики должны следовать при написании кода на Python. Следование этим рекомендациям может значительно улучшить качество вашего кода, сделать его более читаемым и понятным для других разработчиков.
В этой статье мы рассмотрим основные правила, описанные в PEP8, и объясним, как их следовать, чтобы написать чистый, читаемый и поддерживаемый код на Python.
Причины использовать
PEP8 — это руководство по стилю кода для языка программирования Python. Он описывает рекомендации и правила для написания читаемого, понятного и консистентного кода на Python.
PEP8 важен для написания качественного кода на Python по нескольким причинам. Во-первых, он помогает сделать код более читаемым и понятным для других программистов, которые могут работать с вашим кодом. Это особенно важно, если вы работаете в команде или если ваш код будет использоваться другими людьми.
Во-вторых, соблюдение стандартов PEP8 может помочь сделать ваш код более консистентным. Это означает, что ваш код будет выглядеть более единообразно и просто, что упрощает его понимание и обслуживание.
В-третьих, соблюдение стандартов PEP8 может помочь обнаружить ошибки и потенциальные проблемы в вашем коде. Например, если вы используете нестандартное именование переменных или не соблюдаете правила отступов, это может привести к ошибкам или проблемам при чтении вашего кода.
Кроме того, многие инструменты разработки поддерживают стандарты PEP8 и могут помочь вам автоматически проверять соответствие вашего кода этим стандартам.
В целом, соблюдение стандартов PEP8 является важной практикой для написания качественного кода на Python. Он помогает сделать ваш код более читаемым, консистентным и устойчивым к ошибкам.
Основные правила
Основные правила PEP8 — это набор рекомендаций по оформлению кода на Python, который помогает сделать код более читаемым и понятным. Ниже я перечислю несколько основных правил PEP8:
Отступы
Используйте 4 пробела для каждого уровня отступа. Это правило помогает визуально выделить блоки кода и упрощает чтение кода. Использование символов табуляции или пробелов для отступов не рекомендуется, так как это может вызывать проблемы с отображением в разных текстовых редакторах.
Например:
# Правильно: if x == 1: print("x is 1") # Неправильно: if x == 1: print("x is 1")
Максимальная длина строки
Ограничьте длину строки не более чем 79 символами. Если строка длиннее, разбейте ее на несколько строк. Длинные строки могут быть трудны для чтения, особенно когда они выходят за границы окна редактора. Разбиение длинных строк на несколько строк с помощью продолжения строки с помощью символа обратной косой черты \ является хорошей практикой.
Например:
# Правильно: long_string = "This is a really long string that "\ "spans multiple lines." # Неправильно: long_string = "This is a really long string that spans multiple lines."
Пробелы
Используйте один пробел между операторами и операндами. Не используйте пробелы для выделения скобок вокруг аргументов функций. Это правило помогает упростить код и сделать его более читабельным.
Например:
# Правильно: x = 2 + 3 y = (1 + 2) * 3 # Неправильно: x=2+3 y = ( 1 + 2 ) * 3
Именование
Используйте понятные и описательные имена переменных, функций и методов. Для имени переменных используйте строчные буквы, а для имен функций и методов — заглавные буквы. Это правило помогает делать ваш код более читаемым и понятным для других программистов.
Например:
# Правильно: age = 25 name = "John" def calculate_sum(numbers): return sum(numbers) # Неправильно: a = 25 b = "John" def calc_sum(nums): return sum(nums)
Комментарии
Добавляйте комментарии к вашему коду, чтобы объяснить сложные участки кода.
Комментарии должны быть короткими, лаконичными и описательными, они должны помогать другим программистам понимать ваш код. Не используйте комментарии для описания очевидных вещей, таких как присваивание переменной значения, и избегайте комментариев в конце строки.
Например:
# Правильно: # Получаем текущую дату и время current_time = datetime.datetime.now() # Неправильно: current_time = datetime.datetime.now() # Получаем текущую дату и время
Импорты
Импортируйте модули в алфавитном порядке, разделяйте группы импортов пустой строкой и избегайте использования символа * . Это правило помогает упростить импорты и улучшить читабельность кода.
# Правильно: import datetime import os from math import sqrt import requests # Неправильно: import requests, os, datetime from math import * import my_module
Пробелы вокруг операторов
Используйте пустые строки для разделения логически связанных частей кода. Не используйте несколько операторов на одной строке.
Используйте пробелы вокруг операторов (=, +, -, *, /, //, %, и т. д.), но не используйте пробелы вокруг символа индексирования или среза.
Например:
# Правильно: x = 2 + 3 y = x * 4 z = list[0] # Неправильно: x=2+3 y = x*4 z = list [0]
Названия функций и методов
Используйте глаголы в названиях функций и методов, используйте нижнее подчеркивание для разделения слов. Это правило помогает делать код более понятным и легче читаемым.
Например:
# Правильно: def calculate_sum(numbers): return sum(numbers) def get_user_name(user): return user.name # Неправильно: def numbersSum(nums): return sum(nums) def user(user): return user.name
Название переменных
Используйте понятные и описательные названия для переменных, избегайте использования одиночных символов в качестве названий переменных, используйте нижнее подчеркивание для разделения слов.
Например:
# Правильно: total_sum = 0 list_of_numbers = [1, 2, 3, 4] user_name = "John" # Неправильно: t = 0 n = [1, 2, 3, 4] un = "John"
Расположение функций и классов
Располагайте функции и классы логически в вашем коде. Разделяйте функции и классы пустыми строками, чтобы улучшить читабельность кода. Функции должны быть определены перед их использованием.
Например:
# Правильно: def calculate_sum(numbers): return sum(numbers) def main(): list_of_numbers = [1, 2, 3, 4] total_sum = calculate_sum(list_of_numbers) print(f"The total sum is: ") if __name__ == "__main__": main() # Неправильно: def main(): list_of_numbers = [1, 2, 3, 4] total_sum = calculate_sum(list_of_numbers) print(f"The total sum is: ") def calculate_sum(numbers): return sum(numbers) if __name__ == "__main__": main()
Длина строки
Строки не должны быть длиннее 79 символов. Если строка слишком длинная, ее можно разбить на несколько строк, используя скобки, запятые или операторы конкатенации.
Например:
# Правильно: message = "This is a very long message that should be split " \ "into multiple lines for better readability." total_sum = (100 + 200 + 300 + 400 + 500 + 600) # Неправильно: message = "This is a very long message that should be split into multiple lines for better readability." total_sum = 100 + 200 + 300 + 400 + 500 + 600
Тройные кавычки
Используйте тройные кавычки для документации вашего кода. Это помогает другим программистам понимать ваш код и использовать его в своих проектах.
Например:
# Правильно: def calculate_sum(numbers): """ This function calculates the sum of the numbers in the given list. Parameters: numbers (list): A list of numbers to calculate the sum of. Returns: float: The sum of the numbers in the list. """ return sum(numbers) # Неправильно: def calculate_sum(numbers): # This function calculates the sum of the numbers in the given list. return sum(numbers)
Полезные инструменты
Действительно, существует множество инструментов, которые помогают разработчикам Python следовать стандартам PEP8. Эти инструменты включают линтеры и автоматические форматировщики.
Линтеры — это инструменты, которые анализируют код и проверяют его соответствие стандартам PEP8. Они предупреждают разработчиков о нарушениях стандартов PEP8 и других проблемах в их коде. Некоторые из наиболее популярных линтеров для Python включают:
- pylint — это линтер для Python, который проверяет соответствие кода стандартам PEP8. Он также обнаруживает другие проблемы в коде, такие как синтаксические ошибки, неиспользуемые переменные и дублирование кода.
- flake8 — это линтер, который проверяет соответствие кода стандартам PEP8, а также обнаруживает другие проблемы в коде, такие как неиспользуемые импорты и неправильное форматирование строк.
- PyCharm — это IDE для Python, которая включает встроенный линтер, который проверяет соответствие кода стандартам PEP8 и другие проблемы в коде. Он также предлагает рекомендации по исправлению нарушений стандартов PEP8.
Автоматические форматировщики — это инструменты, которые автоматически форматируют код в соответствии со стандартами PEP8. Они упрощают процесс форматирования кода и позволяют разработчикам сосредоточиться на его содержимом. Некоторые из наиболее популярных автоматических форматировщиков для Python включают:
- Black — это автоматический форматировщик кода на Python, который форматирует код в соответствии со стандартами PEP8. Он удаляет неоднозначность в коде и делает его более понятным.
- autopep8 — это инструмент, который автоматически форматирует код в соответствии со стандартами PEP8. Он также может исправлять другие проблемы в коде, такие как синтаксические ошибки.
- YAPF — это автоматический форматировщик кода на Python, который форматирует код в соответствии со стандартами PEP8 и другими рекомендациями по стилю кодирования.
Использование линтеров и автоматических форматировщиков может значительно упростить процесс следования стандартам PEP8 и улучшить качество кода. Например, линтеры могут предупреждать о нарушениях стандартов PEP8 до того, как код будет отправлен на ревью, что помогает избежать ошибок, связанных со стилем кода. Автоматические форматировщики позволяют быстро и легко отформатировать код в соответствии со стандартами PEP8.
Кроме того, многие инструменты интегрируются с популярными средами разработки, такими как PyCharm и VS Code, что упрощает их использование и интеграцию в рабочий процесс разработки.
Важно отметить, что линтеры и автоматические форматировщики не могут полностью заменить ручное форматирование и проверку кода на соответствие стандартам PEP8. Иногда они могут допустить ошибки или предложить неоптимальные решения. Поэтому важно использовать эти инструменты в сочетании с ручной проверкой кода и соблюдением наилучших практик при написании кода на Python.
Дополнительные источники
Существует множество ресурсов и инструментов для дополнительного изучения PEP8 и его реализации в проектах.
Некоторые из них перечислены ниже:
- Официальный документ PEP8: Документ PEP8 можно найти на официальном сайте Python. Он содержит все основные правила и рекомендации по написанию чистого и понятного кода на Python.
- Flake8: Flake8 — это инструмент статического анализа кода на Python, который проверяет соответствие кода стандартам PEP8. Он также проверяет синтаксические ошибки, использование необъявленных переменных и другие нарушения.
- PyCharm: PyCharm — это интегрированная среда разработки (IDE) для Python, которая имеет встроенный инструмент PEP8. Он предупреждает вас, если ваш код нарушает стандарты PEP8, и предлагает исправления.
- Black: Black — это автоматический форматтер кода на Python, который следует стандартам PEP8. Он автоматически форматирует ваш код, чтобы он соответствовал стандартам PEP8, и также может использоваться для автоматического форматирования кода в больших проектах.
- pylint: pylint — это еще один инструмент статического анализа кода на Python, который проверяет соответствие кода стандартам PEP8. Он также предупреждает вас об использовании устаревших или небезопасных конструкций в вашем коде.
- Real Python: Real Python — это онлайн-платформа для изучения Python, которая содержит множество статей, учебных пособий и видеоуроков. Они предлагают руководства по написанию чистого и понятного кода на Python в соответствии с PEP8.
- Python Code Quality Authority: Python Code Quality Authority — это организация, которая управляет несколькими инструментами для проверки качества кода на Python, включая Flake8 и pylint. Они также поддерживают ряд стандартов и рекомендаций для написания чистого и понятного кода на Python.
Заключение
Следование правилам PEP8 поможет вам написать более чистый, понятный и поддерживаемый код на Python. Однако, не стоит забывать, что эти правила не являются абсолютными и всегда могут быть нарушены в некоторых случаях. Важно следить за своим стилем и придерживаться общепринятых стандартов в сообществе Python.
PEP 8 – Style Guide for Python Code
This document gives coding conventions for the Python code comprising the standard library in the main Python distribution. Please see the companion informational PEP describing style guidelines for the C code in the C implementation of Python.
This document and PEP 257 (Docstring Conventions) were adapted from Guido’s original Python Style Guide essay, with some additions from Barry’s style guide [2].
This style guide evolves over time as additional conventions are identified and past conventions are rendered obsolete by changes in the language itself.
Many projects have their own coding style guidelines. In the event of any conflicts, such project-specific guides take precedence for that project.
A Foolish Consistency is the Hobgoblin of Little Minds
One of Guido’s key insights is that code is read much more often than it is written. The guidelines provided here are intended to improve the readability of code and make it consistent across the wide spectrum of Python code. As PEP 20 says, “Readability counts”.
A style guide is about consistency. Consistency with this style guide is important. Consistency within a project is more important. Consistency within one module or function is the most important.
However, know when to be inconsistent – sometimes style guide recommendations just aren’t applicable. When in doubt, use your best judgment. Look at other examples and decide what looks best. And don’t hesitate to ask!
In particular: do not break backwards compatibility just to comply with this PEP!
Some other good reasons to ignore a particular guideline:
- When applying the guideline would make the code less readable, even for someone who is used to reading code that follows this PEP.
- To be consistent with surrounding code that also breaks it (maybe for historic reasons) – although this is also an opportunity to clean up someone else’s mess (in true XP style).
- Because the code in question predates the introduction of the guideline and there is no other reason to be modifying that code.
- When the code needs to remain compatible with older versions of Python that don’t support the feature recommended by the style guide.
Code Lay-out
Indentation
Use 4 spaces per indentation level.
Continuation lines should align wrapped elements either vertically using Python’s implicit line joining inside parentheses, brackets and braces, or using a hanging indent [1]. When using a hanging indent the following should be considered; there should be no arguments on the first line and further indentation should be used to clearly distinguish itself as a continuation line:
# Correct: # Aligned with opening delimiter. foo = long_function_name(var_one, var_two, var_three, var_four) # Add 4 spaces (an extra level of indentation) to distinguish arguments from the rest. def long_function_name( var_one, var_two, var_three, var_four): print(var_one) # Hanging indents should add a level. foo = long_function_name( var_one, var_two, var_three, var_four)
# Wrong: # Arguments on first line forbidden when not using vertical alignment. foo = long_function_name(var_one, var_two, var_three, var_four) # Further indentation required as indentation is not distinguishable. def long_function_name( var_one, var_two, var_three, var_four): print(var_one)
The 4-space rule is optional for continuation lines.
# Hanging indents *may* be indented to other than 4 spaces. foo = long_function_name( var_one, var_two, var_three, var_four)
When the conditional part of an if -statement is long enough to require that it be written across multiple lines, it’s worth noting that the combination of a two character keyword (i.e. if ), plus a single space, plus an opening parenthesis creates a natural 4-space indent for the subsequent lines of the multiline conditional. This can produce a visual conflict with the indented suite of code nested inside the if -statement, which would also naturally be indented to 4 spaces. This PEP takes no explicit position on how (or whether) to further visually distinguish such conditional lines from the nested suite inside the if -statement. Acceptable options in this situation include, but are not limited to:
# No extra indentation. if (this_is_one_thing and that_is_another_thing): do_something() # Add a comment, which will provide some distinction in editors # supporting syntax highlighting. if (this_is_one_thing and that_is_another_thing): # Since both conditions are true, we can frobnicate. do_something() # Add some extra indentation on the conditional continuation line. if (this_is_one_thing and that_is_another_thing): do_something()
(Also see the discussion of whether to break before or after binary operators below.)
The closing brace/bracket/parenthesis on multiline constructs may either line up under the first non-whitespace character of the last line of list, as in:
my_list = [ 1, 2, 3, 4, 5, 6, ] result = some_function_that_takes_arguments( 'a', 'b', 'c', 'd', 'e', 'f', )
or it may be lined up under the first character of the line that starts the multiline construct, as in:
my_list = [ 1, 2, 3, 4, 5, 6, ] result = some_function_that_takes_arguments( 'a', 'b', 'c', 'd', 'e', 'f', )
Tabs or Spaces?
Spaces are the preferred indentation method.
Tabs should be used solely to remain consistent with code that is already indented with tabs.
Python disallows mixing tabs and spaces for indentation.
Maximum Line Length
Limit all lines to a maximum of 79 characters.
For flowing long blocks of text with fewer structural restrictions (docstrings or comments), the line length should be limited to 72 characters.
Limiting the required editor window width makes it possible to have several files open side by side, and works well when using code review tools that present the two versions in adjacent columns.
The default wrapping in most tools disrupts the visual structure of the code, making it more difficult to understand. The limits are chosen to avoid wrapping in editors with the window width set to 80, even if the tool places a marker glyph in the final column when wrapping lines. Some web based tools may not offer dynamic line wrapping at all.
Some teams strongly prefer a longer line length. For code maintained exclusively or primarily by a team that can reach agreement on this issue, it is okay to increase the line length limit up to 99 characters, provided that comments and docstrings are still wrapped at 72 characters.
The Python standard library is conservative and requires limiting lines to 79 characters (and docstrings/comments to 72).
The preferred way of wrapping long lines is by using Python’s implied line continuation inside parentheses, brackets and braces. Long lines can be broken over multiple lines by wrapping expressions in parentheses. These should be used in preference to using a backslash for line continuation.
Backslashes may still be appropriate at times. For example, long, multiple with -statements could not use implicit continuation before Python 3.10, so backslashes were acceptable for that case:
with open('/path/to/some/file/you/want/to/read') as file_1, \ open('/path/to/some/file/being/written', 'w') as file_2: file_2.write(file_1.read())
(See the previous discussion on multiline if-statements for further thoughts on the indentation of such multiline with -statements.)
Another such case is with assert statements.
Make sure to indent the continued line appropriately.
Should a Line Break Before or After a Binary Operator?
For decades the recommended style was to break after binary operators. But this can hurt readability in two ways: the operators tend to get scattered across different columns on the screen, and each operator is moved away from its operand and onto the previous line. Here, the eye has to do extra work to tell which items are added and which are subtracted:
# Wrong: # operators sit far away from their operands income = (gross_wages + taxable_interest + (dividends - qualified_dividends) - ira_deduction - student_loan_interest)
To solve this readability problem, mathematicians and their publishers follow the opposite convention. Donald Knuth explains the traditional rule in his Computers and Typesetting series: “Although formulas within a paragraph always break after binary operations and relations, displayed formulas always break before binary operations” [3].
Following the tradition from mathematics usually results in more readable code:
# Correct: # easy to match operators with operands income = (gross_wages + taxable_interest + (dividends - qualified_dividends) - ira_deduction - student_loan_interest)
In Python code, it is permissible to break before or after a binary operator, as long as the convention is consistent locally. For new code Knuth’s style is suggested.
Blank Lines
Surround top-level function and class definitions with two blank lines.
Method definitions inside a class are surrounded by a single blank line.
Extra blank lines may be used (sparingly) to separate groups of related functions. Blank lines may be omitted between a bunch of related one-liners (e.g. a set of dummy implementations).
Use blank lines in functions, sparingly, to indicate logical sections.
Python accepts the control-L (i.e. ^L) form feed character as whitespace; many tools treat these characters as page separators, so you may use them to separate pages of related sections of your file. Note, some editors and web-based code viewers may not recognize control-L as a form feed and will show another glyph in its place.
Source File Encoding
Code in the core Python distribution should always use UTF-8, and should not have an encoding declaration.
In the standard library, non-UTF-8 encodings should be used only for test purposes. Use non-ASCII characters sparingly, preferably only to denote places and human names. If using non-ASCII characters as data, avoid noisy Unicode characters like z̯̯͡a̧͎̺l̡͓̫g̹̲o̡̼̘ and byte order marks.
All identifiers in the Python standard library MUST use ASCII-only identifiers, and SHOULD use English words wherever feasible (in many cases, abbreviations and technical terms are used which aren’t English).
Open source projects with a global audience are encouraged to adopt a similar policy.
Imports
- Imports should usually be on separate lines:
# Correct: import os import sys
# Wrong: import sys, os
It’s okay to say this though:
# Correct: from subprocess import Popen, PIPE
- Standard library imports.
- Related third party imports.
- Local application/library specific imports.
You should put a blank line between each group of imports.
import mypkg.sibling from mypkg import sibling from mypkg.sibling import example
However, explicit relative imports are an acceptable alternative to absolute imports, especially when dealing with complex package layouts where using absolute imports would be unnecessarily verbose:
from . import sibling from .sibling import example
from myclass import MyClass from foo.bar.yourclass import YourClass
If this spelling causes local name clashes, then spell them explicitly:
import myclass import foo.bar.yourclass
Module Level Dunder Names
Module level “dunders” (i.e. names with two leading and two trailing underscores) such as __all__ , __author__ , __version__ , etc. should be placed after the module docstring but before any import statements except from __future__ imports. Python mandates that future-imports must appear in the module before any other code except docstrings:
"""This is the example module. This module does stuff. """ from __future__ import barry_as_FLUFL __all__ = ['a', 'b', 'c'] __version__ = '0.1' __author__ = 'Cardinal Biggles' import os import sys
String Quotes
In Python, single-quoted strings and double-quoted strings are the same. This PEP does not make a recommendation for this. Pick a rule and stick to it. When a string contains single or double quote characters, however, use the other one to avoid backslashes in the string. It improves readability.
For triple-quoted strings, always use double quote characters to be consistent with the docstring convention in PEP 257.
Whitespace in Expressions and Statements
Pet Peeves
Avoid extraneous whitespace in the following situations:
-
Immediately inside parentheses, brackets or braces:
# Correct: spam(ham[1], eggs: 2>)
# Wrong: spam( ham[ 1 ], eggs: 2 > )
# Correct: foo = (0,)
# Wrong: bar = (0, )
# Correct: if x == 4: print(x, y); x, y = y, x
# Wrong: if x == 4 : print(x , y) ; x , y = y , x
# Correct: ham[1:9], ham[1:9:3], ham[:9:3], ham[1::3], ham[1:9:] ham[lower:upper], ham[lower:upper:], ham[lower::step] ham[lower+offset : upper+offset] ham[: upper_fn(x) : step_fn(x)], ham[:: step_fn(x)] ham[lower + offset : upper + offset]
# Wrong: ham[lower + offset:upper + offset] ham[1: 9], ham[1 :9], ham[1:9 :3] ham[lower : : step] ham[ : upper]
# Correct: spam(1)
# Wrong: spam (1)
# Correct: dct['key'] = lst[index]
# Wrong: dct ['key'] = lst [index]
# Correct: x = 1 y = 2 long_variable = 3
# Wrong: x = 1 y = 2 long_variable = 3
Other Recommendations
- Avoid trailing whitespace anywhere. Because it’s usually invisible, it can be confusing: e.g. a backslash followed by a space and a newline does not count as a line continuation marker. Some editors don’t preserve it and many projects (like CPython itself) have pre-commit hooks that reject it.
- Always surround these binary operators with a single space on either side: assignment ( = ), augmented assignment ( += , -= etc.), comparisons ( == , < , >, != , <> , = , in , not in , is , is not ), Booleans ( and , or , not ).
- If operators with different priorities are used, consider adding whitespace around the operators with the lowest priority(ies). Use your own judgment; however, never use more than one space, and always have the same amount of whitespace on both sides of a binary operator:
# Correct: i = i + 1 submitted += 1 x = x*2 - 1 hypot2 = x*x + y*y c = (a+b) * (a-b)
# Wrong: i=i+1 submitted +=1 x = x * 2 - 1 hypot2 = x * x + y * y c = (a + b) * (a - b)
# Correct: def munge(input: AnyStr): . def munge() -> PosInt: .
# Wrong: def munge(input:AnyStr): . def munge()->PosInt: .
# Correct: def complex(real, imag=0.0): return magic(r=real, i=imag)
# Wrong: def complex(real, imag = 0.0): return magic(r = real, i = imag)
When combining an argument annotation with a default value, however, do use spaces around the = sign:
# Correct: def munge(sep: AnyStr = None): . def munge(input: AnyStr, sep: AnyStr = None, limit=1000): .
# Wrong: def munge(input: AnyStr=None): . def munge(input: AnyStr, limit = 1000): .
# Correct: if foo == 'blah': do_blah_thing() do_one() do_two() do_three()
Rather not:
# Wrong: if foo == 'blah': do_blah_thing() do_one(); do_two(); do_three()
# Wrong: if foo == 'blah': do_blah_thing() for x in lst: total += x while t 10: t = delay()
Definitely not:
# Wrong: if foo == 'blah': do_blah_thing() else: do_non_blah_thing() try: something() finally: cleanup() do_one(); do_two(); do_three(long, argument, list, like, this) if foo == 'blah': one(); two(); three()
When to Use Trailing Commas
Trailing commas are usually optional, except they are mandatory when making a tuple of one element. For clarity, it is recommended to surround the latter in (technically redundant) parentheses:
# Correct: FILES = ('setup.cfg',)
# Wrong: FILES = 'setup.cfg',
When trailing commas are redundant, they are often helpful when a version control system is used, when a list of values, arguments or imported items is expected to be extended over time. The pattern is to put each value (etc.) on a line by itself, always adding a trailing comma, and add the close parenthesis/bracket/brace on the next line. However it does not make sense to have a trailing comma on the same line as the closing delimiter (except in the above case of singleton tuples):
# Correct: FILES = [ 'setup.cfg', 'tox.ini', ] initialize(FILES, error=True, )
# Wrong: FILES = ['setup.cfg', 'tox.ini',] initialize(FILES, error=True,)
Comments
Comments that contradict the code are worse than no comments. Always make a priority of keeping the comments up-to-date when the code changes!
Comments should be complete sentences. The first word should be capitalized, unless it is an identifier that begins with a lower case letter (never alter the case of identifiers!).
Block comments generally consist of one or more paragraphs built out of complete sentences, with each sentence ending in a period.
You should use one or two spaces after a sentence-ending period in multi-sentence comments, except after the final sentence.
Ensure that your comments are clear and easily understandable to other speakers of the language you are writing in.
Python coders from non-English speaking countries: please write your comments in English, unless you are 120% sure that the code will never be read by people who don’t speak your language.
Block Comments
Block comments generally apply to some (or all) code that follows them, and are indented to the same level as that code. Each line of a block comment starts with a # and a single space (unless it is indented text inside the comment).
Paragraphs inside a block comment are separated by a line containing a single # .
Inline Comments
Use inline comments sparingly.
An inline comment is a comment on the same line as a statement. Inline comments should be separated by at least two spaces from the statement. They should start with a # and a single space.
Inline comments are unnecessary and in fact distracting if they state the obvious. Don’t do this:
x = x + 1 # Increment x
But sometimes, this is useful:
x = x + 1 # Compensate for border
Documentation Strings
Conventions for writing good documentation strings (a.k.a. “docstrings”) are immortalized in PEP 257.
- Write docstrings for all public modules, functions, classes, and methods. Docstrings are not necessary for non-public methods, but you should have a comment that describes what the method does. This comment should appear after the def line.
- PEP 257 describes good docstring conventions. Note that most importantly, the «»» that ends a multiline docstring should be on a line by itself:
"""Return a foobang Optional plotz says to frobnicate the bizbaz first. """
"""Return an ex-parrot."""
Naming Conventions
The naming conventions of Python’s library are a bit of a mess, so we’ll never get this completely consistent – nevertheless, here are the currently recommended naming standards. New modules and packages (including third party frameworks) should be written to these standards, but where an existing library has a different style, internal consistency is preferred.
Overriding Principle
Names that are visible to the user as public parts of the API should follow conventions that reflect usage rather than implementation.
Descriptive: Naming Styles
There are a lot of different naming styles. It helps to be able to recognize what naming style is being used, independently from what they are used for.
The following naming styles are commonly distinguished:
- b (single lowercase letter)
- B (single uppercase letter)
- lowercase
- lower_case_with_underscores
- UPPERCASE
- UPPER_CASE_WITH_UNDERSCORES
- CapitalizedWords (or CapWords, or CamelCase – so named because of the bumpy look of its letters [4]). This is also sometimes known as StudlyCaps. Note: When using acronyms in CapWords, capitalize all the letters of the acronym. Thus HTTPServerError is better than HttpServerError.
- mixedCase (differs from CapitalizedWords by initial lowercase character!)
- Capitalized_Words_With_Underscores (ugly!)
There’s also the style of using a short unique prefix to group related names together. This is not used much in Python, but it is mentioned for completeness. For example, the os.stat() function returns a tuple whose items traditionally have names like st_mode , st_size , st_mtime and so on. (This is done to emphasize the correspondence with the fields of the POSIX system call struct, which helps programmers familiar with that.)
The X11 library uses a leading X for all its public functions. In Python, this style is generally deemed unnecessary because attribute and method names are prefixed with an object, and function names are prefixed with a module name.
In addition, the following special forms using leading or trailing underscores are recognized (these can generally be combined with any case convention):
- _single_leading_underscore : weak “internal use” indicator. E.g. from M import * does not import objects whose names start with an underscore.
- single_trailing_underscore_ : used by convention to avoid conflicts with Python keyword, e.g.
tkinter.Toplevel(master, class_='ClassName')
Prescriptive: Naming Conventions
Names to Avoid
Never use the characters ‘l’ (lowercase letter el), ‘O’ (uppercase letter oh), or ‘I’ (uppercase letter eye) as single character variable names.
In some fonts, these characters are indistinguishable from the numerals one and zero. When tempted to use ‘l’, use ‘L’ instead.
ASCII Compatibility
Identifiers used in the standard library must be ASCII compatible as described in the policy section of PEP 3131.
Package and Module Names
Modules should have short, all-lowercase names. Underscores can be used in the module name if it improves readability. Python packages should also have short, all-lowercase names, although the use of underscores is discouraged.
When an extension module written in C or C++ has an accompanying Python module that provides a higher level (e.g. more object oriented) interface, the C/C++ module has a leading underscore (e.g. _socket ).
Class Names
Class names should normally use the CapWords convention.
The naming convention for functions may be used instead in cases where the interface is documented and used primarily as a callable.
Note that there is a separate convention for builtin names: most builtin names are single words (or two words run together), with the CapWords convention used only for exception names and builtin constants.
Type Variable Names
Names of type variables introduced in PEP 484 should normally use CapWords preferring short names: T , AnyStr , Num . It is recommended to add suffixes _co or _contra to the variables used to declare covariant or contravariant behavior correspondingly:
from typing import TypeVar VT_co = TypeVar('VT_co', covariant=True) KT_contra = TypeVar('KT_contra', contravariant=True)
Exception Names
Because exceptions should be classes, the class naming convention applies here. However, you should use the suffix “Error” on your exception names (if the exception actually is an error).
Global Variable Names
(Let’s hope that these variables are meant for use inside one module only.) The conventions are about the same as those for functions.
Modules that are designed for use via from M import * should use the __all__ mechanism to prevent exporting globals, or use the older convention of prefixing such globals with an underscore (which you might want to do to indicate these globals are “module non-public”).
Function and Variable Names
Function names should be lowercase, with words separated by underscores as necessary to improve readability.
Variable names follow the same convention as function names.
mixedCase is allowed only in contexts where that’s already the prevailing style (e.g. threading.py), to retain backwards compatibility.
Function and Method Arguments
Always use self for the first argument to instance methods.
Always use cls for the first argument to class methods.
If a function argument’s name clashes with a reserved keyword, it is generally better to append a single trailing underscore rather than use an abbreviation or spelling corruption. Thus class_ is better than clss . (Perhaps better is to avoid such clashes by using a synonym.)
Method Names and Instance Variables
Use the function naming rules: lowercase with words separated by underscores as necessary to improve readability.
Use one leading underscore only for non-public methods and instance variables.
To avoid name clashes with subclasses, use two leading underscores to invoke Python’s name mangling rules.
Python mangles these names with the class name: if class Foo has an attribute named __a , it cannot be accessed by Foo.__a . (An insistent user could still gain access by calling Foo._Foo__a .) Generally, double leading underscores should be used only to avoid name conflicts with attributes in classes designed to be subclassed.
Note: there is some controversy about the use of __names (see below).
Constants
Constants are usually defined on a module level and written in all capital letters with underscores separating words. Examples include MAX_OVERFLOW and TOTAL .
Designing for Inheritance
Always decide whether a class’s methods and instance variables (collectively: “attributes”) should be public or non-public. If in doubt, choose non-public; it’s easier to make it public later than to make a public attribute non-public.
Public attributes are those that you expect unrelated clients of your class to use, with your commitment to avoid backwards incompatible changes. Non-public attributes are those that are not intended to be used by third parties; you make no guarantees that non-public attributes won’t change or even be removed.
We don’t use the term “private” here, since no attribute is really private in Python (without a generally unnecessary amount of work).
Another category of attributes are those that are part of the “subclass API” (often called “protected” in other languages). Some classes are designed to be inherited from, either to extend or modify aspects of the class’s behavior. When designing such a class, take care to make explicit decisions about which attributes are public, which are part of the subclass API, and which are truly only to be used by your base class.
With this in mind, here are the Pythonic guidelines:
- Public attributes should have no leading underscores.
- If your public attribute name collides with a reserved keyword, append a single trailing underscore to your attribute name. This is preferable to an abbreviation or corrupted spelling. (However, notwithstanding this rule, ‘cls’ is the preferred spelling for any variable or argument which is known to be a class, especially the first argument to a class method.) Note 1: See the argument name recommendation above for class methods.
- For simple public data attributes, it is best to expose just the attribute name, without complicated accessor/mutator methods. Keep in mind that Python provides an easy path to future enhancement, should you find that a simple data attribute needs to grow functional behavior. In that case, use properties to hide functional implementation behind simple data attribute access syntax. Note 1: Try to keep the functional behavior side-effect free, although side-effects such as caching are generally fine. Note 2: Avoid using properties for computationally expensive operations; the attribute notation makes the caller believe that access is (relatively) cheap.
- If your class is intended to be subclassed, and you have attributes that you do not want subclasses to use, consider naming them with double leading underscores and no trailing underscores. This invokes Python’s name mangling algorithm, where the name of the class is mangled into the attribute name. This helps avoid attribute name collisions should subclasses inadvertently contain attributes with the same name. Note 1: Note that only the simple class name is used in the mangled name, so if a subclass chooses both the same class name and attribute name, you can still get name collisions. Note 2: Name mangling can make certain uses, such as debugging and __getattr__() , less convenient. However the name mangling algorithm is well documented and easy to perform manually. Note 3: Not everyone likes name mangling. Try to balance the need to avoid accidental name clashes with potential use by advanced callers.
Public and Internal Interfaces
Any backwards compatibility guarantees apply only to public interfaces. Accordingly, it is important that users be able to clearly distinguish between public and internal interfaces.
Documented interfaces are considered public, unless the documentation explicitly declares them to be provisional or internal interfaces exempt from the usual backwards compatibility guarantees. All undocumented interfaces should be assumed to be internal.
To better support introspection, modules should explicitly declare the names in their public API using the __all__ attribute. Setting __all__ to an empty list indicates that the module has no public API.
Even with __all__ set appropriately, internal interfaces (packages, modules, classes, functions, attributes or other names) should still be prefixed with a single leading underscore.
An interface is also considered internal if any containing namespace (package, module or class) is considered internal.
Imported names should always be considered an implementation detail. Other modules must not rely on indirect access to such imported names unless they are an explicitly documented part of the containing module’s API, such as os.path or a package’s __init__ module that exposes functionality from submodules.
Programming Recommendations
- Code should be written in a way that does not disadvantage other implementations of Python (PyPy, Jython, IronPython, Cython, Psyco, and such). For example, do not rely on CPython’s efficient implementation of in-place string concatenation for statements in the form a += b or a = a + b . This optimization is fragile even in CPython (it only works for some types) and isn’t present at all in implementations that don’t use refcounting. In performance sensitive parts of the library, the ».join() form should be used instead. This will ensure that concatenation occurs in linear time across various implementations.
- Comparisons to singletons like None should always be done with is or is not , never the equality operators. Also, beware of writing if x when you really mean if x is not None – e.g. when testing whether a variable or argument that defaults to None was set to some other value. The other value might have a type (such as a container) that could be false in a boolean context!
- Use is not operator rather than not . is . While both expressions are functionally identical, the former is more readable and preferred:
# Correct: if foo is not None:
# Wrong: if not foo is None:
