Требования к организации и оформлению кода (Python)¶
- Table of contents
- Требования к организации и оформлению кода (Python)
- Концептуальные требования
- Внешний вид кода
- Соглашения по именам
- Пробелы в выражениях и инструкциях
- Методы, поля и свойства классов
- Документирование кода
Концептуальные требования¶
Система классов программы должна быть осмысленной и отвечать парадигме объектно-ориентированного программирования.
Методы не должны занимать более 25 строк. Если метод занимает большее количество строк, значит он выполняет несколько независимых операций и требует разделения на более мелкие методы.
Категорически запрещается дублирование одинакового кода!
Запрещается собственная реализация средств, имеющих аналоги в стандартной библиотеке Python. Во всех случаях, когда возможно использование библиотечных классов Python, они должны быть использованы.
Рекомендуется использовать шаблоны проектирования во всех случаях, когда это представляется уместным.
Не допускается выполнять оптимизацию кода, ухудшающую его качество, если это не является действительно необходимым. В случае применения оптимизации, ее реализация должна быть скрыта внутри класса/модуля.
Все возможные ошибочные ситуации должны корректно обрабатываться. Сообщения об ошибках должны быть максимально информативными.
Сравнение с
None
должно осуществляться только с помощью операцииis
:
if x is None and z is not None: pass
Внешний вид кода¶
Используйте 4 пробела на один уровень отступа. Символы табуляции запрещены.
Ограничьте максимальную длину строки 90 символами.
В случае если строка больше 90 символов, осуществите перенос на новую строку с двойным отступом относительно текущего отступа.
Отделяйте функции верхнего уровня и определения классов двумя пустыми строками. Определения методов внутри класса отделяйте одной пустой строкой.
Не рекомендуется размещение нескольких операторов в одной строке, кроме случаев, когда это не ухудшает удобочитаемости программы.
При импорте имён из модулей с помощью инструции
from
запрещается использовать форму со звёздочкой.
Соглашения по именам¶
Имена должны быть осмысленными словами (или словосочетаниями в значении соответствующей части речи) английского языка. Для локальных переменных допускается использование сокращённых имён (например, i) с сохранением общепринятого контекста (i только для управляющей переменной цикла).
Имена пакетов и модулей — существительные в нижнем регистре, слова разделяются подчёркиваниями (program_installer).
Имена классов — существительные или словосочетания в значении существительных: в нижнем регистре, первые буквы слов — в верхнем регистре, разделители слов не используются (ClientInfo); имена классов-исключений заканчиваются на Error (InvalidUserError).
Имена полей и локальных переменных — существительные в нижнем регистре, слова разделены подчёркиваниями (file_size).
Имена методов — глаголы в нижнем регистре (либо словосочетания, отражающие действия), слова разделены подчёркиваниями (remove_file). Для имён методов, возвращающих значения величин допускается использование существительных (например, volume вместо eval_volume), а не глаголов, если только это не приведёт к неоднозначности.
Имена констант — существительные или словосочетания в верхнем регистре, слова разделены подчёркиваниями (INVALID_RECORD_COLOR).
Пробелы в выражениях и инструкциях¶
Избегайте использования пробелов в следующих ситуациях:
- Сразу после или перед скобками (круглыми, фигурными и квадратными)
spam(ham[1], {eggs: 2})
- Сразу перед запятой, точкой с запятой, двоеточием:
if x == 4: print x, y; x, y = y, x
- Сразу перед открывающей скобкой, после которой начинается список аргументов при вызове функции:
spam(1)
- Сразу перед открывающей скобкой, после которой следует индекс или срез:
dict['key'] = list[index]
- Всегда окружайте знаки бинарных операций одним пробелом с каждой стороны: присваивание (=, +=, -=, *= /=), сравнения (==, <, >, !=, <>, <=, >=, 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)
- Используйте условную операцию
if—else
вместо оператора в тех случаях, когда соответствующее выражение умещается на одной строке. В противном случае используйте операторif
, размещая его ветви на отдельных строках:
result = "several" if len(list) > 1 else "zero or one" if self.__draggedPath < MainView.__MIN_DRAG_PATH and not self._isButtonInside(*nextPos): result = 0 else: result = MainView.__MIN_DRAG_PATH + additionalDragPath * 2
Методы, поля и свойства классов¶
Используйте cls в качестве первого аргумента метода класса (class method).
Используйте self в качестве первого аргумента метода экземпляра объекта (instance method).
Имена частных методов должны начинаться с одного символа подчеркивания.
Все поля определяются частными (с префиксом из двух подчёркиваний).
Все свойства, для которых в классе имеются поля, определяются сразу после комментария, описывающего класс. Примеры методов определения свойств приведены в примере ниже.
from util.attribute import * # подключаем модуль с необходимыми функциями class Person(object): # необходимо использовать new-style classes ''' Basic descriptive object for typical person name: the name location: approximate location ''' readable('name') # предоставляем доступ к атрибуту __name только на чтение writable('location') # предоставляем полный доступ к атрибуту __location def __init__(self): # инциализация атрибутов класса self.__name = 'Jone Dove' self.__location = 'New York' self.__bankAccount = '999-444-888-887' self.__job = 'Sales manager' def getJob(self): return self.__job; def employ(self, value): self.__job = value if value is None: self.__job = 'unemployed' # предоставляем нестандартный способ доступа к атрибуту __job job = property(getJob, employ, None, 'Place of employment')
Пример доступа к свойствам и атрибутам класса Person:
person = Person() # print person.__bankAccount # нельзя обращаться к частным атрибутам! print person.name # выводит на экран содержимое __name # person.name = 'Mikle Russ' # нельзя выполнить присваивание print person.location # выводит на экран содержимое __address person.location = 'London' # можно выполнить присваивание print person.job # выводит на экран результат вызова getJob person.job = None # происходит вызов метода employ с аргументом value=None
Документирование кода¶
Обязательными являются документационные комментарии для всех модулей, классов, полей и методов.
!/images/smileys/fixme.gif! Как документировать поля классов? Epydoc или однострочные комментарии?
Для документирования следует использовать Epydoc и язык разметки Epytext #the-epytext-markup-language
Обязательно наличие тегов @type, @param, @return, @rtype, @raise для функций и методов (если они имеют соответствующие атрибуты):
def _parseRoot(root): ''' Save XML tree information into mind map object @param root: XML tree root @type root: lxml Element @raise Exception: if no root node found @return: mind map object @rtype: MindMap '''
- Если действие метода/функции тривиальное и его описание присутствует в теге @return, разрешается пропустить общий текст комментария к данному методу/функции:
@property def allNodeAttributes(self): ''' @return: list of pairs (attributeName, attributeValue) all node attributes @rtype: list ''' return self.__nodeAttribute.attributesMap.items()
- Если значение аргумента метода/функции понятно из его имени и имени самого метода/функции, разрешается пропустить тег @param. Чаще это исключения относится к методам классов, выполняющих тривиальные действия по получению/добавлению/установке значений полей:
def addChild(self, child): ''' Add a child node to the current node @type child: Node ''' self.__children.append(child)
Каждый модуль должен быть документирован в одном общем стиле (см. существующие модули проекта). Для создания исходных текстов может предоставляться специальный скрипт
srccreate
.Информация об авторе указывается для всех классов, а также модулей, не содержащих классы. В качестве автора указывается человек, создавший данный класс или модуль. Информация об авторах дополняется при внесении существенных изменений в класс другими участниками проекта.
Комментарии должны быть только на английском языке.
Комментарии не должны содержать орфографических и пунктуационных ошибок.