|
|
Строка 1: |
Строка 1: |
| | [[Category:devel]] |
| | {{MovedFromWikiEterSoftRu|devel/Python}} |
|
| |
|
| === Стандарт оформления исходного кода на Python === | | === Общие сведения о разработке на Python === |
| | |
| Данный стандарт выработан с учетом опыта разработки нескольких проектов и обязателен к использованию всеми программистами Etersoft, разрабатывающими на языке Python.
| |
| | |
| За основу взяты Google Coding Style, Qt Coding Style и некоторые другие.
| |
| * [http://qt.gitorious.org/qt/pages/QtCodingStyle http://qt.gitorious.org/qt/pages/QtCodingStyle]
| |
| * [http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml]
| |
| | |
| | |
| === Отступы ===
| |
| | |
| В качестве отступов в исходном коде можно использовать символы табуляции, а не пробелы. Ширина табуляции может настраиваться в текстовом редакторе так, как удобно для восприятия разработчику, в отличие от пробелов, количество которых нельзя уменьшить или увеличить в коде, не переписывая его весь регекспами.
| |
| | |
| В рамках одного файла с исходным кодом (в дальнейшем — модуля) ни в коем случае нельзя использовать разные виды отступа (пробелы и табуляции одновременно), так как интерпретатор воспримет их некорректно.
| |
| | |
| Некоторые сотрудники, (например, sin@) считают более правильным использование пробелов. Поскольку с его мнением трудно не считаться :-), то было принято следующее правило: тип отступов определяет первый коммитер проекта, его руководитель. Остальные следуют его примеру. Кроме этого пункта, остальные правила кодинг-стайла остаются неизменными.
| |
| | |
| | |
| ''Настройка величины табуляции для разных редакторов''
| |
| * Vim: для настройки введите "ESC :set ts=6", таким образом символ табуляции визуально будет выглядеть, как 6 пробелов. Для сохранения настройки надо прописать опцию в конфиг: "echo "set ts=6" >> /.vimrc". Для быстрого преобразования кода, содержащего 2, 4, 6 или 8 пробелов к стандартным табам, можно воспользоваться таким мапом клавиш:
| |
| :<pre>set wildmenu
| |
| set wcm=<Tab>
| |
| | |
| menu SpacesRefactoring.[2\ Spaces\ to\ Tab] :%s#^\( \{2}\)\+#\=repeat("\t", len(submatch(0))/2)#g<Cr>
| |
| menu SpacesRefactoring.[4\ Spaces\ to\ Tab] :%s#^\( \{4}\)\+#\=repeat("\t", len(submatch(0))/4)#g<Cr>
| |
| menu SpacesRefactoring.[6\ Spaces\ to\ Tab] :%s#^\( \{6}\)\+#\=repeat("\t", len(submatch(0))/6)#g<Cr>
| |
| menu SpacesRefactoring.[8\ Spaces\ to\ Tab] :%s#^\( \{8}\)\+#\=repeat("\t", len(submatch(0))/8)#g<Cr>
| |
| | |
| menu SpacesRefactoring.[Tab\ to\ 2\ Spaces] :%s#^\(\t\+\)#\=repeat(" ", len(submatch(0))*2)#g<Cr>
| |
| menu SpacesRefactoring.[Tab\ to\ 4\ Spaces] :%s#^\(\t\+\)#\=repeat(" ", len(submatch(0))*4)#g<Cr>
| |
| menu SpacesRefactoring.[Tab\ to\ 6\ Spaces] :%s#^\(\t\+\)#\=repeat(" ", len(submatch(0))*6)#g<Cr>
| |
| menu SpacesRefactoring.[Tab\ to\ 8\ Spaces] :%s#^\(\t\+\)#\=repeat(" ", len(submatch(0))*8)#g<Cr>
| |
| | |
| nmap <F2> :emenu SpacesRefactoring.<Tab></pre>
| |
| :Нажатие F2 вызовет меню из нескольких пунктов, где можно выбрать, сколько пробелов конвертировать в табы и наоборот, привести табы к несокльким пробелам.
| |
| | |
| | |
| === Имена объектов ===
| |
| | |
| * Имена локальных переменных или членов класса должны состоять только из строчных букв, и не содержать сокращений. Несколько слов в названии переменной должны разделятся символом прочерка (_), но не использованием строчной буквы.
| |
| :<pre># Неправильно:
| |
| bigRedBall = 4
| |
| my_fnct = lambda : None
| |
| | |
| # Правильно:
| |
| big_red_ball = 4
| |
| my_func = lambda : None</pre>
| |
| :Допускается использование общепринятых и распространенных и сокращений, таких, как count, func, err, ptr, const, iter и других. Сокращений, типа intern_err_lvl (internal_error_level) следует избегать.
| |
| | |
| * Следует избегать названий переменных, состоящий из одной буквы, таких, как i, j, x, y, однако допускается использование их для определения однозначно ассоциируемых понятий, таких, как координаты на плоскости. В случае, если вы хотите использовать такую переменную как счетчик внутри цикла, к ее имени следует добавлять постфикс "_count".
| |
| :<pre># Неправильно:
| |
| x = 0
| |
| while x < 5 :
| |
| pass # Некоторый код...
| |
| | |
| # Правильно:
| |
| x_count = 0
| |
| while x_count < 5 :
| |
| pass # Некоторый код...</pre>
| |
| | |
| * При использовании переменной в качестве элемента итерации или для обозначения ее вида следует использовать постфиксы "_list", "_item", "_dict", "_key", "_flag" (для булевых переменных) и некоторые другие. Если переменная представляет собой экземпляр класс, в терминологии библиотеки являющегося типом, то нужно подписывать другие постфиксы, например, для объекта QWidget в Qt имя будет состоять из нескольких слов плюс постфикс "_widget". Типы QList и QStringList будут иметь одинаковый постфикс "_list", поскольку оба могут быть итерируемы. Элемент итерации для этих типов должен состоять из полного названия объекта плюс префикса "_item", например, "servers_list" и "servers_list_item".
| |
| :Исключением можно считать элемент, который сам по себе является более сложным типом данных, например, виджетом. Имя такого элемента определяется произвольным образом с учетом остальных правил и не оканчивается суффиксом "_item".
| |
| :<pre># Неправильно:
| |
| for i in strings_list :
| |
| pass
| |
| | |
| # Правильно:
| |
| for strings_list_item in strings_list :
| |
| pass</pre>
| |
| | |
| * Недопускается объявление разных переменных в одну строчку, однако разрешается присваивание одного значения нескольким переменным.
| |
| :<pre># Неправильно:
| |
| first = 0; last = 5
| |
| begin = 0; end = 5;
| |
| | |
| # Правильно:
| |
| first = begin = 0
| |
| last = end = 5</pre>
| |
| :Такой код можно использовать только в том случае, когда переменные логически близки друг к другу и только при объявлении. Счетчики надо объявлять отдельно.
| |
| | |
| * Глобальные переменные нужно именовать строчными буквами, начиная каждое слово с прописной буквы. Аббревиатуры в именах таких переменных так же следует именовать исходя из этого правила, то есть, большая буква будет только в начале слова.
| |
| :<pre># Неправильно:
| |
| XMLHandler_Default = None
| |
| | |
| # Правильно:
| |
| DefaultXmlHandler = None</pre>
| |
| :Допускается использование прочерка, в случае, если одна часть имени переменной отражает одну логическую составляющую, а друга часть - другую:
| |
| :<pre>F1_Key = 1
| |
| F2_Key = 2
| |
| Return_Key = 3</pre>
| |
| | |
| * В Python отсутствует такая возможность, как объявление макросов в стиле C или констант C++, поэтому, для создания глобальных (на модуль) констант нужно использовать имена, состоящие из прописныз букв, разделенных подчеркиваниями:
| |
| :<pre>LIBS_DIR_PATH = "/usr/lib"</pre>
| |
| | |
| * Имена классов и метаклассов должны состоять из нескольких слов, каждая первая буква каждого слова должна быть прописной.
| |
| :<pre># Неправильно:
| |
| class foo_bar(object) :
| |
| pass
| |
| | |
| # Правильно:
| |
| class FooBar(object) :
| |
| pass</pre>
| |
| | |
| * Имя функции члена-класса или просто функции модуля должно состоять из строчных букв, начинающихся с прописных. Первая буква имени функции должна быть строчной.
| |
| :<pre># Неправильно:
| |
| def some_function() :
| |
| pass
| |
| | |
| # Правильно:
| |
| def someFunction() :
| |
| pass</pre>
| |
| :
| |
| * Исключение: если одна функция/класс вложена в другую (т.е. замыкание), то внутренняя функция/класс считается локальной переменной и именуется в соответствии с правилами для переменных.
| |
| | |
| * Для переменных-членов класса используйте имена, начинающиеся с "_" и "__". Первое обозначает, что переменная является закрытой, но ее переназначение допускается при наследовании. Второй тип переменных является полностью закрытым и используется только ввнутри класса родителя, не пересекаясь с дочерним классом, переменная в котором может иметь точно такое же имя.
| |
| | |
| * Не используйте "_" и "__" для имен функций и классов. Группируйте их по признаку доступа визуально и указывайте комментарий "# Public", "# Private", "Handlers" и другие. Подробнее [http://www.network-theory.co.uk/docs/pytut/PrivateVariables.html тут].
| |
| | |
| | |
| ==== Разделители ====
| |
| | |
| * Используйте одну пустую строку для логического разделения процедур.
| |
| | |
| * Используйте две пустых строки для логического разделения закрытых/открытых функций/переменных/классов на модуль или класс. Сначала пишите группу закрытых объектов, затем группу публичных.
| |
| | |
| * Операторы присвоения, логические операторы и любые другие нужно разделять пробелами.
| |
| | |
| * Перед символом ":" обозначающим начало блока, нужно ставить один пробел.
| |
| :<pre>Неправильно:
| |
| def more(x):
| |
| return x**2
| |
| f = lambda a: more(a)
| |
| | |
| Правильно:
| |
| def more(x) :
| |
| return x ** 2
| |
| func = lambda more(a) : a</pre>
| |
| | |
| | |
| ==== Использование скобок ====
| |
| | |
| * Группируйте скобками операции независимо от действия приоритета.
| |
| :<pre># Неправильно:
| |
| if a or b and c :
| |
| pass
| |
|
| |
|
| # Правильно:
| | Это язык программирования высокого уровня, относящийся к группе языков с динамической типизацией и автоматической сборкой мусора. Программа на Python компилируется в байт-код и исполняется на виртуальной машине. |
| if a or (b and c) :
| |
| pass
| |
|
| |
|
| # Неправильно:
| | Этот раздел посвящен советам для Python-разработчиков в Etersoft, а так же принятым внутренним стандартам. |
| x = a or b and c
| |
|
| |
|
| # Правильно:
| | [[Special:Prefixindex/]] |
| x_flag = a or (b and c)</pre>
| |
| | |
| * По обеим сторонам от внутреннего содержимого скобок не нужно ставить пробелы. Исключения составляют lambda-функции, строчные операторы if-else, и заполнение списка.
| |
| :<pre>dir_list = [ item for item in os.listdir(".") if item[0] != "." ]
| |
| pow = ( lambda x, n : x ** n )
| |
| line = ( "foo" if True else "bar" )</pre>
| |
| :Круглые скобки не нужно указывать, если выражение является единственным вложенным аргументом других скобок. Наличие отступов сохраняется.
| |
| :<pre>foo( "foo" if True else "bar" ).</pre>
| |
| :Используйте пробелы внутри скобок и табуляцию каждой строки, если содержимое занимает несколько строк, для всех операторов, кроме вызовов функций и конструкторов.
| |
| | |
| * В остальном, ставьте скобки только там, где они действительно нужны.
| |
| | |
| | |
| ==== Комментарии ====
| |
| | |
| * Комментарии должны начинаться с символа "#", имеющего после себя один пробел. Комментарии больше длиннее 5 строк должны начинаться и заканчиваться специальной последовательностью """ для многострочных комментариев (docstring) Python.
| |
| | |
| | |
| ==== Исключения ====
| |
| * Допускаются любые исключения, если ваш код с использованием вышеописанных правил выглядит не очень хорошо или же здравый смысл подсказывает, что правило в данном случае не подходит. Красота кода остается главным критерием этого кодинг-стайла.
| |
| | |
| === Ссылки ===
| |
| * [[CodingStyle]]
| |
| | |
| [[Category:devel]]
| |
| {{MovedFromWikiEterSoftRu|devel/Python/CodingStyle}}
| |