Код читается гораздо чаще, чем пишется.
Важно улучшать читаемость кода
и обеспечивать его единообразие.
Главное - быть последовательным.
4 пробела вместо табуляции
Выравнивать строки кода по открывающему разделителю
(с неявной линией в скобках),
либо с использованием висячего отступа
(тогда на первой линии не должно быть аргументов).
Строка кода 79 символов
(можно договориться в команде до 100).
Строка документации и комментариев 72 символа.
Перенос обратной косой чертой \ лучше избегать.
Перенос после логического оператора (and, or).
Пустые строки:
- Одна пустая строка - методы внутри класса,
логические разделы внутри функции и группы импорта. - Две пустые строки - классы и функции верхнего уровня.
- Дополнительные пустые строки - для различных групп похожих функций.
Кодировка в UTF-8.
Только английские слова.
Каждый импорт на отдельной строке, кроме from.
Порядок импортов:
- Из стандартной библиотеки.
- Из сторонней библиотеки.
- Из модулей текущего проекта.
Лучше абсолютный импорт, а не относительный (from .),
кроме случаев излишней подробности.
Нет шаблонам импортов (import *).
Если вместо Git используется Subversion, CVS или RCS,
то для контроля версий:
"""Мой модуль. Делает полезные вещи."""
__version__ = "$Revision: 1a40d4eaa00b $"
# $Source$
import os
import sysЛучше выбрать двойные или одинарные кавычки
и использовать этот вариант в проекте.
Лишь иногда можно сделать исключение ради читаемости.
Тройные кавычки всегда двойные.
Нет пробелам внутри ()``{}``[]
Нет пробелам перед , ; :
Нет пробелам перед открывающейся скобкой,
при вызове функции, индексе, срезе.
Нет более одного пробелам вокруг оператора
(мол, для выравнивания с другими).
Нет пробелам вокруг операторов с высоким приоритетом
(для отделения от других операторов).
По пробелу всегда вокруг бинарного оператора:
- присваивания
=,+=,-=,*=и т.д. - сравнения
==,<,>,!=,<>,<=,>=,in,not in,is,is not - логические
and,or,not
По пробелу вокруг ->
Нет пробелам вокруг =, когда случай именованного аргумента
или значение параметра по умолчанию.
Исключение: аннотация аргумента со значением по умолчанию.
Нет нескольким командам в одной строке.
Когда ожидается, что некий список будет расширяться,
каждое значение с новой строки,
и в конце запятая.
Закрывающая скобка при этом с новой строки.
Главное не ставить замыкающую запятую на той же строке.
Исключение: если это обязательно для создания кортежа.
Комментарии не должны противоречить коду.
Поэтому после изменения кода
надо изменить комментарий.
Комментарий - законченное предложение.
Первое слово с большой буквы (кроме переменных).
Никогда не изменять регистр переменной.
Короткий комментарий - без точки в конце.
В блоке комментариев - после каждого точка.
Два пробела после точки,
кроме последнего предложения.
Комментарии всегда на английском.
У блока комментариев отступ такой же,
что и у кода, который он объясняет после него.
Абзац блока комментариев - одиночный #
и пробел после него
Избегать комментарии на той же строке.
Комментарий не должен объяснять очевидное.
Строки документации для всех публичных:
модулей, функций, классов, методов
(для приватных необязательно,
но лучше тоже кратко написать).
Шаблон строки документации:
"""Return a foobang
Optional plotz says to frobnicate the bizbaz first.
"""Для однострочной документации закрывающиеся кавычки на той же строке.
Если в старой библиотеке правила нарушаются,
нужно писать в ее стиле.
Главный принцип - имена, видные,
как чаcть общественного API
должны отражать использование, а не реализацию.
_name - типо для внутренних нужд
(from M import * не будет импортировать).
class_ - для избежания конфликтов
с ключевыми словами python.
Атрибут класса Base.__name автоматически
переименовывается в Base._Base__name -
но она все равно доступна,
просто доступ затруднен.
__init__ - для магических методов.
Никогда не использовать однобуквенные
названия l, O, I (иногда неотличимы от 1, 0).
Должна быть совместимость с ASCII.
Модули - module, my_package.
Если модуль C/C++ дает Python какой-то модуль,
то такой должен начинаться с _ (_socket).
Классы - CapWords.
Причем соглашение о встроенных именах в Python:
1-2 слова слитно,
а CapWords для исключений и встроенных констант.
Типы переменных - CapWords,
лучше котороткие имена T, AnyStr, Num.
Исключения - классы => CapWords.
Можно написать Error в конце.
Нужно писать механизм __all__,
чтобы глобальные переменные не экспортировались.
Функции и глобальные переменные - my_name,
либо mixedCase, где уже такой стиль.
self - первый аргумент для метода экземпляра.
cls - первый аргумент для @classmethod.
Если возникают конфликты имен,
лучше class_ или синоним, чем clss.
Публичные методы и переменные экземпляров - my_name.
Непубличные - _name.
__name лучше только чтобы избежать конфликтов имен.
Константы - MAX_OVERFLOW.
Заранее решить, будет метод класса или экземпляр
публичным или непубличным.
Если есть сомнения - делать непубличным.
Публичные будут использовать другие,
а непубличные вы можете и удалить или изменить когда-нибудь.
Приватных атрибутов по сути в Python не бывает.
При проектировании базового класса для наследников
решить и указать, какие атрибуты публичные,
какие для API подклассов (защищенные)
и какие только для внутри базового класса (приватные).
Публичные атрибуты - понятные имена
без сложных методов доступа и изменения.
Можно использовать property, чтобы скрыть
функциональную реализацию за синтаксисом доступа.
Но избегать вычислительно затратных операций.
__name для базового класса, который
скрывает от своих наследников.
Но тогда:
- У подкласса не должно быть такое же имя.
- Откладка и
__getattr__()менее удобные. - Не всем такое нравится, поэтому искать компромисс.
Гарантия обратной совместимости -
для публичных интерфейсов.
=> Чтобы можно было четко разделять
публичные и внутренние интерфейсы.
=> Модулям объявлять о публичном API
через __all__ атрибут.
__all__ = [], когда нет публичного API.
Пространство имен считается внутренним (приватным),
=> интерфейс внутри тоже внутренний.
Нет косвенному импорту,
кроме явно документированной части API модуля.
Коду не зависеть от разных реализаций языка
(PyPy, Jython, IronPython, Pyrex, Psyco) -
например, от эффективных операций у кого-то из.
Сравнения с None ТОЛЬКО через is None, is not None.
При реализации сравнения лучше реализовать сразу все 6:
__eq__, __ne__, __lt__, __le__, __gt__, __ge__.
Можно воспользоваться functools.total_ordering()
для недостающих методов.
Лучше def, чем lambda.
Наследовать лучше от Exception,так как от BaseException для тех, которые не надо перехватывать.
raise X from Y при явной замене,
проследить, чтобы без потери информации.
При генерации исключений лучше
новый синтаксис raise ValueError('message').
Перехватывать конкретные ошибки,
а не простой except.
В худшем случае except Exception:.
Исключение:
- Вывод пользователю всего
- Нужен некоторый код после перехвата,
а потом вновь бросить для обработки в другом месте.
Но лучше
try...finally.
Для ошибок операционной системы лучше
явна иерархия исключений, чем errno.
Минимум кода в try...except.
with для ресурса на локальном участке кода.
with с отдельной функцией,
если что-то кроме получение или освобождение ресурса.
Лучше строковые методы, чем модуль string.
Лучше .startswith() и .endswith(), чем срезы строк.
Лучше isinstance(), чем прямое сравнение типов.
Для проверки str и unicode
есть общий класс basestring.
[], () и "" - это False, так что лучше писать без len:
if not seq.
Опасны важные пробелы в конце строковых констант.
if cond: лучше, чем == True или is True.
Не использовать return, break, continue внутри finally,
так как при выходе за пределы набора finally отменяется исключение.