InfoCity
InfoCity - виртуальный город компьютерной документации
Реклама на сайте







Размещение сквозной ссылки

 

Руководство стиля Python


Гвидо ван Россум
Перевод: С.Тезадов


Несогласованность - признак непрофессионализма


Руководство стиля касается согласованности. Следование этому руководству является важным. Согласованность внутри проекта важнее. Согласованность в пределах одного модуля или функции еще важнее.

Но что важнее всего, это знание, где следует быть несовместимым -- иногда руководство стиля просто не применимо. В сомнительных случаях принимайте наиболее подходящие решения. Посмотрите на другие примеры и решайте что выглядит лучше. И не колеблясь, спрашивайте!

Содержание


  • Разбивка -- как пользоваться табуляцией, пробелами и новой строкой.
  • Комментирование -- правильное использование комментариев (и документирующих строк).
  • Имена -- различные соглашения касательно имен.

Разбивка


Абзацный отступ


Используйте стандартный Emacs Python-режим: 4 пробела для одного уровня отступа. Для действительно старого кода, чтобы не получилось разнобоя, можно продолжить использование 8 пробелов. В этом случае, для Emacs добавляйте в конец следующее:
# Local Variables:
# py-indent-offset: 8
# End:

Табуляция или пробелы?


Один уровень отступа - 4 пробела. Два уровня - одна табуляция. Три уровня - табуляция и 4 пробела, и т.д. Python не будет возражать, если Вы сделаете отступ одной строки с помощью 8 пробелов, а следующей строки с помощью табуляции -- считается, что это одинаковый отступ. Замена всех табуляций пробелами более живуча в некоторых редакторах на Mac или PC (которые по умолчанию выводят символ табуляции в виде 4 пробелов, вместо 8, как повелел Господь) но это может быть проделано при передаче на такие платформы.

Максимальная длина строки


Все еще существует много устройств, ограниченных 80 символьными строками. Перенос, который они делают, выглядит неприглядно. Поэтому, пожалуйста ограничивайте строки максимум 79 символами (Emacs переносит строки длиной 80 символов).

Для переноса длинных строк предпочтительнее использовать неявное продолжение строк, заключенных в круглые, квадратные и фигурные скобки. В случае необходимости, можно добавить дополнительные скобки в выражение, но иногда использование обратного слеша выглядит лучше. Удостоверьтесь, что сдвигаете продолжение строки соответственно. Emacs Python-режим делает это корректно. Несколько примеров:

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"
        Blob.__init__(self, widt, height,
                      color, emphasis, highlight)

Пустые строки


Разделяйте определения функций и классов двумя пустыми стоками. Методы внутри класса следует разделять одной пустой строкой. Дополнительные пустые строки можно использовать (умеренно) для выделения групп связанных функций. В перечне связанных однострочных определений допускается пренебрежение пустыми строками (напр., в наборе макетов).

Когда определения методов разделены пустыми строками, следует разделить также строку `class' и определение первого метода.

В функциях умеренно используйте пустые строки для выделения логически связанных частей.

Пробелы в выражениях и операторах


Любимая Мозоль


Я ненавижу пробелы в следующих местах:
  • Сразу после скобок: spam( ham[ 1 ], { eggs: 2 } ). Всегда пишите так: spam(ham[1], {eggs: 2}).

  • Непосредственно перед запятой, точки с запятой или двоеточием: if x == 4 : print x , y ; x , y = y , x. Лучше пишите так: if x == 4: print x, y; x, y = y, x.

  • Перед открывающей скобкой, содержащей список аргументов вызываемой функции: spam (1). Правильный вариант: spam(1).

  • Непосредственно перед открывающей скобкой, содержащей индекс или сечение, как здесь: dict ['key'] = list [index]. Следует писать так: dict['key'] = list[index].

  • Более одного пробела вокруг оператора присваивания (или другого оператора) для выравнивания со следующей строкой, вроде этого:
    x             = 1
    y             = 2
    long_variable = 3
    
    Всегда пишите так:
    x = 1
    y = 2
    long_variable = 3
    
(Не утруждайтесь спорами о вышеперечисленном -- я использую этот стиль свыше 15 лет.)

Другие рекомендации


  • Всегда отделяйте бинарные операции с обеих сторон одним пробелом: присваивание (=), сравнение (==, <, >, !=, <>, <=, >=, in, not in, is, is not), логические (and, or, not).

  • Пользуйтесь наиболее подходящим размещением пробелов вокруг арифметических операций. Будьте всегда последовательны во вставке пробелов с обеих сторон бинарной операции. Несколько примеров:
    i = i+1
    submitted = submitted + 1
    x = x*2 - 1
    hypot2 = x*x + y*y
    c = (a+b) * (a-b)
    c = (a + b) * (a - b)
    
  • Пробелы вокруг знака '=' не нужны, когда он указывает на наличие ключевого аргумента или значения параметра по умолчанию. Например:
    def complex(real, imag=0.0):
        return magic(r=real, i=imag)
    

Комментарии


Наличие комментариев, противоречащих коду, хуже, чем их отсутствие. Всегда отдавайте приоритет обновлению комментариев, когда модифицируется код!

Если комментарий является фразой или предложением, первое слово следует писать с прописной буквы, за исключением, когда это идентификатор, начинающийся со строчной буквы (никогда не пишите идентификатор в другом регистре!).

Если комментарий короткий, будет лучше не ставить в конце точку. Блочные комментарии обычно состоят из одного или нескольких абзацев, включающих целые предложения, каждое из которых завершается точкой.

Можно ставить два пробела после точки, завершающей предложение.

Python программисты, живущие не в англо-говорящих странах: пожалуйста, пишите комментарии на английском, если Вы на все 120% не уверены, что ни один человек, не знающий Вашего языка, не будет читать Ваш код.

Блочные комментарии


Блочные комментарии в основном относятся к некоторому (или всему) последующему коду, и сдвигаются на тот же уровень, что и код. Каждая строка блочных комментариев начинается с # и одного пробела (исключение: если это не сдвинутый текст внутри комментария). Абзацы внутри блочных комментариев разделяются строкой, содержащей просто #. Блочные комментарии лучше всего отделять пустыми строками -- перед и после них (или двумя строками в начале и одной пустой строкой в конце, для блочных комментариев, расположенных перед новой секцией определений функций).

Встроенные комментарии


Встроенный комментарий располагается в той же строке что и оператор. Такие комментарии следует использовать умеренно. Они отделяются от оператора по крайней мере двумя пробелами и начинаются с # и одного пробела.

Встроенные комментарии излишни и, фактически, только отвлекают, если констатируют очевидное. Не делайте таких вещей:

x = x+1                 # Инкремент x
Но иногда такое полезно:
x = x+1                 # Компенсация для рамки

Документирующие строки


Все модули должны иметь документирующие строки, и все функции и классы, экспортируемые модулем, также следует снабжать документацией. Общедоступные (public) методы (включая конструктор __init__) тоже надо документировать.

Документирующая строка скрипта (независимой программы) должна быть доступна в виде сообщения "usage", печатаемого при обращении к скрипту с некорректными или отсутствующими аргументами, или, возможно, с опцией "-h" для помощи). Такая строка должна описывать назначение скрипта, синтаксис командной строки, переменные окружения и файлы. "Usage" сообщения могут быть довольно подробными (занимая несколько полных экранов) и должны быть достаточны для новых пользователей, чтобы правильно воспользоваться командами. Кроме этого, такие сообщения должны предоставлять полную информацию по всем аргументам и опциям для продвинутых пользователей.

Для согласованности, всегда используйте """тройку двойных кавычек""" вокруг документирующих строк.

Существует две формы: одно- и много-строчное документирование.

Однострочное документирование


Одинарные строки предназначены для действительно очевидных случаев. Они должны на самом деле занимать одну строку. Пример:
def kos_root():
    """Верни путь к корневому каталогу KOS."""
    global _kos_root
    if _kos_root: return _kos_root
    ...
Примечания:
  • Даже если строка (string) умещается в одной строчке (line), используйте тройку парных кавычек. Потом будет проще расширять строку.
  • Закрывающие кавычки в той же строке что и открывающие. Для одинарных строк так выглядит лучше.
  • Не стоит вставлять пустых строк ни перед, ни после документирующей строки.
  • Документирующая строка - это фраза, завершаемая точкой. Она предписывает эффект функции в виде команды ("Сделай это", "Верни то"), а не описывает, напр., не пишите "Возвращает путь..."

Многострочное документирование


Многострочное документирование состоит из подытоживающей строки, которая есть обычная однострочная документирующая строка, с последующей пустой строкой и более подробным описанием. Подытоживающая строка может быть использована утилитами автоматического индексирования. Следовательно, важно чтобы она занимала одну строчку и была отделена от последующего текста пустой строкой.

Вся документирующая строка пишется с таким же отступом как у открывающих кавычек (см. пример ниже). Из второй и последующих строчек утилитами обработки документации будет вырезаться такой же объем отступа как у первой непустой строки, последующей за первой строчкой документирующей строки. При этом сохраняется относительный отступ последующих строчек.

Я рекомендую вставлять пустую строку между последним параграфом в многострочной документации и ее закрывающими кавычками, размещая кавычки в отдельной строке. Это способ для использования Emacs команды fill-paragraph.

Я также рекомендую вставлять пустую строку перед и после всех документирующих строк (одно- или много-строчных), которые пишутся для классов. Вообще говоря, методы класса отделяются друг от друга одной строчкой и документирующая строка нуждается в отделении от первого метода пустой строкой. Для симметрии, я предпочитаю оставлять пустую строку между заголовком класса и документирующей строкой. Когда дело касается функций, обычно таких требований не возникает, за исключением случая, когда тело функции состоит из набора отделенных друг от друга секций. Тогда отнеситесь к документирующей строке как еще к одной секции и вставьте предшествующую пустую строку.

Документирование модуля должно включать список классов, исключений и функций (и других объектов), которые экспортируются модулем, с однострочным итоговым описанием для каждого из них. (Такие описания обычно содержат меньше деталей, чем итоговые описания в документирующих строках объектов.)

Документирующая строка для функции или метода должна описывать их поведение, их аргументы, возвращаемые значения, побочный эффект, инициируемые исключения и ограничения на их вызов. Следует также указать необязательные аргументы. Напишите, являются ли ключевые аргументы частью интерфейса.

Документирующая строка класса суммирует его поведение и список общедоступных (public) методов и переменных экземпляра. Если от класса предполагается наследовать и он обладает дополнительным интерфейсом для потомков, этот интерфейс следует привести отдельно (в документирующей строке). Конструктор класса описывается в документации для метода __init__. Другие методы должны документироваться в их собственных документирующих строках.

Если класс является потомком и свое поведение главным образом наследует, его описание упоминает об этом и должно суммировать разницу. Используйте глагол "override" для указания, что метод потомка заменяет метод предка и не обращается к нему. Если же метод вызывает такой же метод родителя (в добавление к своему собственному поведению), тогда пишите глагол "extend".

Не используйте соглашения Emacs о записи аргументов функций или методов прописными буквами в текущем тексте. Python чувствителен к регистру и имена аргументов могут быть использованы для ключевых аргументов, следовательно, в документирующей строке нужно корректно писать имена аргументов. Лучше всего будет, если Вы перечислите каждый аргумент в отдельной строке, с двумя дефисами, отделяющими имя от описания, вот так:

def complex(real=0.0, imag=0.0):
    """Сформируй комплексное число.

    Ключевые аргументы:
    real -- вещественная часть (по умолчанию 0.0)
    imag -- мнимая часть (по умолчанию 0.0)

    """
    if imag == 0.0 and real == 0.0: return complex_zero
    ...

Учет версий


Если Вам нужно иметь RCS или CVS корку в исходном файле, то можно поступить как показано ниже.
__version__ = "$Revision: 1.3 $"
# $Source: /home/guido/ftp/pub/www.python.org/doc/essays/RCS/styleguide.html,v $
Эти строчки размещаются после документирующей строки модуля, до начала кода, отделяя их сверху и снизу пустой строкой.

Соглашения по именованию


В библиотеке Python соглашения по именованию находятся в некотором беспорядке, так что, мы никогда не получим их полностью последовательно. Тем не менее, вот некоторые направления.

Описательный: стили имен


Существует куча различных стилей именования. Полезно уметь определить что за стиль используется в каждом конкретном случае, независимо от того, зачем это делается. Обычно различают следующие стили имен:
  • x (одинарная строчная буква)
  • X (одинарная прописная буква)
  • lowercase (нижний регистр)
  • lower_case_with_underscores (нижний регистр с подчеркиванием)
  • UPPERCASE (верхний регистр)
  • UPPER_CASE_WITH_UNDERSCORES (верхний регистр с подчеркиванием)
  • CapitalizedWords (или CapWords -- слова с прописной буквы)
  • mixedCase (отличается от CapitalizedWords начальной строчной буквой!)
  • Capitalized_Words_With_Underscores (безобразно!)
Существует также стиль, использующий короткий уникальный префикс для группировки вместе связанных имен. Это редко используется в Python, но я упомянул об этом для полноты картины. Например, функция os.stat() возвращает тьюпл с элементами, традиционно носящими имена вроде st_mode, st_size, st_mtime и так далее. Библиотека X11 использует префикс X для всех своих общедоступных функций. (В Python этот стиль обычно не считается необходимым, поскольку имена атрибутов и методов префиксируются объектом, а имена функции -- именем модуля.)

В дополнение, еще различаются следующие особые формы с использованием предшествующего или завершающего подчеркивания (они часто могут быть комбинированы с любым соглашением):

  • _single_leading_underscore: слабый индикатор "внутреннего использования" (напр., "from M import *" не импортирует объекты, чьи имена начинаются подчеркиванием).
  • single_trailing_underscore_: используется, по соглашению, во избежание конфликта с ключевыми словами Python, напр., Tkinter.Toplevel(master, class_="ClassName").
  • __double_leading_underscore: приватные имена в классах, начиная с Python 1.4.
  • __double_leading_and_trailing_underscore__: "волшебные" объекты или атрибуты, обитающие в пространствах имен, контролируемых пользователем, напр., __init__, __import__ или __file__. Иногда они определяются пользователем для инициирования "волшебного" поведения (напр., перегрузка операций); а иногда они вставляются инфраструктурой для собственного использования или в целях отладки. Поскольку инфраструктура (свободно определяемая как интерпретатор Python и стандартная библиотека) может решить расширить свой список "волшебных" атрибутов в будущих версиях, пользовательский код должен стараться воздерживаться от использования этого соглашение в собственных целях. Пользовательский код, который стремится стать частью инфраструктуры, может комбинировать это с коротким префиксом внутри подчеркиваний, напр., __bobo_magic_attr__.

Предписывающий: соглашения имен


Имена модулей


Модули можно называть либо в СмешанномРегистре, либо в нижнемрегистре. Не существует однозначного предписания для решения что предпочесть. Модуль, экспортирующий один класс (или несколько тесно связанных классов, плюс некоторая дополнительная поддержка) обычно именуется в смешанном регистре, при этом названия модуля и класса совпадают (напр., стандартный модуль StringIO). Модули, экспортирующие набор функций, обычно имеют имена полностью в нижнем регистре.

Поскольку имена модулей отображаются на имена файлов, а некоторые файловые системы не различают регистра и усекают длинные имена, важно, чтобы имена модулей выбирались достаточно короткими и не конфликтовали с другими модулями, чьи имена отличаются лишь регистром. Это не проблема для Unix, но будет проблемой при переносе кода на Mac или Windows.

Появляется еще одно соглашение, что когда расширяющий модуль, написанный на C или C++ имеет сопровождающий Python модуль, который предоставляет более высокий уровень интерфейса (напр., более объектно-ориентированный), то имя Python модуля пишется ПрописнымиБуквами, в то время как C/C++ модуль именуется в нижнем регистре с предшествующим подчеркиванием (напр., Tkinter/_tkinter).

"Пакеты" (группа модулей, поддерживаемых модулем "ni") в основном имеют короткие имена в нижнем регистре.

Имена классов


Почти без исключения, имена классов используют CapWords соглашение. Классы для внутреннего использования имеют дополнительно лидирующее подчеркивание.

Имена исключений


Если модуль обладает лишь одним исключением, инициируемым во всех случаях, оно обычно называется "error" или "Error". Насколько я могу сказать, встроенные (расширяющие) модули используют "error" (напр., os.error), в то время как Python модули предпочитают "Error" (напр., xdrlib.Error).

Имена функций


Простые функции, экспортируемые модулем, могут использовать как стиль CapWords, так и lowercase (или lower_case_with_underscores). У меня нет более устойчивого предпочтения, но думаю, стиль CapWords уместней для функций, предоставляющих основную функциональность (напр., nstools.WorldOpen()), а lowercase лучше для "утилитных" функций (напр., pathhack.kos_root()).

Имена глобальных переменных


(Давайте надеяться, что такие переменные предполагаются использовать лишь в пределах одного модуля.) Правила для них такие же как для экспортируемых функций. Модули, спроектированные для использования через "from M import *", должны префиксировать свои глобальные переменные (в том числе внутренние функции и классы) одним символом подчеркивания, во избежания их экспортирования.

Имена методов


Хмм, с ними та же история что и для функций. При использовании ILU, имеется хорошая договоренность: для методов, опубликованных с помощью интерфейса ILU, использовать CapWords. А lowercase -- для методов, доступных другим классам или для функций, являющихся частью реализации объектного типа. Применяйте одно начальное подчеркивание для "внутренних" методов и переменных экземпляра (класса) если исключена возможность конфликта с атрибутами потомка или предка, или когда потомок действительно может нуждаться в доступе к ним. В случае, если важно чтобы только текущий класс имел доступ к атрибуту, используйте два начальных подчеркивания (приватные для класса имена, введенные в Python 1.4). (Но при этом понимайте, что Python содержит достаточно лазеек, сквозь которые настойчивый пользователь может получить к ним доступ, напр., через атрибут __dict__. Только ILU или ограничивающий режим Python будут XXX

[Содержание]


Реклама на InfoCity

Яндекс цитирования



Финансы: форекс для тебя








1999-2009 © InfoCity.kiev.ua