Пользователь
0,0
рейтинг
27 мая 2013 в 14:30

Разработка → Советы Google по кодированию на языке Python. Часть вторая: советы по форматированию исходного кода


Доброго времени суток. Вот и пришло время для публикации второй части так понравившегося многим хабровчанам перевода стайл гайда для языка Python от компании Google, (первая часть бережно хранится хабром). Теперь мы коснемся напрямую форматирования исходного кода на языке программирования Python. Как известно, чистота — залог здоровья, а чистота программного кода — залог уважения коллег и (в идеале) поощрения от кого-нибудь свыше. Вообще, Python сам по себе является хорошо читаемым языком, и даже синтаксис данного языка призывает к порядку в коде (и, как следствие — в голове). Но каждый из нас сам себе документатор и сам себе творец оформления. А как уже говорилось однажды — ко мнению авторитетных товарищей нельзя не прислушиваться. Итак, вторая часть Google Python Style Guide — Python Style Rules ждет Вас под катом. И pdf тут как тут.

Python Style Rules


Точки с запятой

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

Длина строки

Максимальная длина строки - 80 символов
Исключения

  • Длинные строки импорта
  • URL в комментариях

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

Хорошо:

foo_bar(self, width, height, color='black', design=None, x='foo',
        emphasis=None, highlight=0)

if (width == 0 and height == 0 and
    color == 'red' and emphasis == 'strong'):


Когда Ваш текст не помещается в одну строку, используйте скобки для явного объединения строк.

x = ('This will build a very long long '
     'long long long long long long string')

Что касается комментариев, располагайте длинный URL, если это необходимо, на одной строке.

Хорошо:

 # See details at
 # http://www.example.com/us/developer/documentation/api/content/v2.0/csv_file_name_extension_full_specification.html


Плохо:

 # See details at
 # http://www.example.com/us/developer/documentation/api/content/\
 # v2.0/csv_file_name_extension_full_specification.html

Обратите внимание на отступ элемента в строке выше (смотрите раздел про отступы, чтобы получить разъяснения).

Скобки

Используйте скобки экономно
Не используйте их (скобки) с выражением return или с условной конструкцией, если не требуется организовать перенос строки. (Смотрите выше). Однако скобки хорошо использовать для создания кортежей.

Хорошо:

if foo:
    bar()
while x:
    x = bar()
if x and y:
    bar()
if not x:
    bar()
return foo
for (x, y) in dict.items(): ...


Плохо:

if (x):
    bar()
if not(x):
    bar()
return (foo)


Отступы

Никогда не используйте табуляцию или смесь табуляции и пробелов
В случае, когда вы подразумеваете перенос строки, вы должны выровнять каждый перенесенный элемент по вертикали так, как описано в примере о длине строк, либо используя отступ в 4 пробела, в этом случае не должно быть ни одного аргумента на первой строке.

Хорошо:

# Aligned with opening delimiter
foo = long_function_name(var_one, var_two,
						 var_three, var_four)

# 4-space hanging indent; nothing on first line
foo = long_function_name(
				var_one, var_two, var_three,
				var_four)


Плохо:

# Stuff on first line forbidden
foo = long_function_name(var_one, var_two,
     var_three, var_four)

# 2-space hanging indent forbidden
foo = long_function_name(
  var_one, var_two, var_three,
  var_four)


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

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

Пробелы

Следуйте стандартным типографским правилам, касающимся использования пробела в пунктуации
Никаких пробелов внутри каких-либо скобок.
Хорошо: 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]
Окружайте бинарные операторы одиночными пробелами с каждой стороны, это касается присваивания (=), операторов сравнения (==, <, >, !=, <>, <=, >=, in, not in, is, is not), и булевых операторов (and, or, not). Используйте как вам покажется правильно окружение
пробелами по отношению к арифметическим операторам, но всегда расстановка пробелов по обоим сторонам бинарного оператора будет придавать целостность Вашему коду.
Хорошо: x == 1
Плохо: x<1
Не используйте пробелы по сторонам знака "=", когда вы используете его чтобы указать на именованный аргумент или значение по-умолчанию.

Хорошо:

def complex(real, imag=0.0): return magic(r=real, i=imag)

Плохо:

def complex(real, imag = 0.0): return magic(r = real, i = imag)

Не используйте пробелы для вертикального выравнивания кусков последовательных строк, так как такие выравнивания оказываются обременительными. (Относится и к :,#,=, и т.д.):

Хорошо:

foo = 1000  # comment
long_name = 2  # comment that should not be aligned

dictionary = {
      'foo': 1,
      'long_name': 2,
      }

Плохо:

  foo       = 1000  # comment
  long_name = 2     # comment that should not be aligned

  dictionary = {
      'foo'      : 1,
      'long_name': 2,
      }


Строка #! (хэш-бэнг)

Большинство файлов .py не нуждаются в запуске через строку #!
Запускайте главный файл программы с помощью #!/usr/bin/python. Эта строка используется ядром, чтобы найти интерпретатор Python, но игнорируется Python-ом, когда импортируются модули. Это необходимо для файла, который выполняется напрямую.

Комментарии

Будьте уверены в использовании правильного стиля
Будьте уверены в использовании правильного стиля для модуля, функции, метода или строкового комментария.

Строки документации.

Python имеет уникальный стиль комментирования — строки документации. Строка документации это строка, которая является первой конструкцией в пакете, модуле, классе или функции. Такие строки могут быть экспортированы автоматически с помощью атрибута объекта __doc__ и используются pydoc-ом. (Попробуйте запустить pydoc на своем модуле, чтобы увидеть как это выглядит.) Наше соглашение по строкам документации велит использовать три двойные кавычки для обрамления такой строки. Строки документации должны быть организованы как суммарная строка (одна физическая строка), сносящаяся по кол-ву символов, знаку вопроса или восклицательному знаку, следующим за пустой строкой, а затем остальные строки документации с позиции курсора в качестве первой кавычки первой строки. Ниже описано еще больше информации по оформлению строк документирования.

Модули

Каждый файл должен содержать в себе шаблон лицензии. Выберите подходящий шаблон лицензии для вашего проекта.(Например, Apache 2.0, BSD, LGPL, GPL).

Функции и методы

Используемый в этом разделе термин (функция) относится к методам, функциям и генераторам.
Функция должна иметь строку документации во всех случаях, кроме описанных ниже:
  • Не видима снаружи модуля
  • Очень короткая
  • Очевидная (легко читаемая)

Строка документирования должна давать достаточно информации, чтобы оформить вызов функции без чтения ее исходного кода. Строка документирования должна описывать синтаксис вызова функции и ее семантику, но не должна описывать ее реализацию. Для хитрого кода комментарии внутри исходного кода более предпочтительны, чем строки документации. Определенные аспекты функции должны быть задокументированы в специальных секциях, перечисленных ниже. Каждая секция начинается со строки заголовка, которая заканчивается точкой. Секции должны иметь отступ в два пробела, за исключением заголовочной.
Args:
Перечислите каждый параметр по имени. Описание должно следовать сразу за именем и быть разделено точкой и пробелом. Если описание слишком длинное, чтобы уместить его в в 80 символов, используйте подвешенный отступ в 2 или 4 пробела (будьте последовательны в оформлении всего файла).
Описание должно ссылаться на требуемый тип(ы) и назначение аргумента. Если функция позволяет *foo (списки аргументов переменной длины) и/или **bar (произвольный набор аргументов типа ключ-значение), они должны быть записаны как *foo и **bar.
Returns: (либо Yields для генераторов)
Опишите тип и семантику возвращаемого значения. Если функция всегда возвращает None, то данный раздел необязателен.
Raises:
Список всех исключений, которые возможны для данного интерфейса.

def fetch_bigtable_rows(big_table, keys, other_silly_variable=None):
   """Fetches rows from a Bigtable.

   Retrieves rows pertaining to the given keys from the Table instance
   represented by big_table.  Silly things may happen if
   other_silly_variable is not None.

   Args:
       big_table: An open Bigtable Table instance.
       keys: A sequence of strings representing the key of each table row
          to fetch.
       other_silly_variable: Another optional variable, that has a much
          longer name than the other args, and which does nothing.

   Returns:
       A dict mapping keys to the corresponding table row data
       fetched. Each row is represented as a tuple of strings. For
       example:

       {'Serak': ('Rigel VII', 'Preparer'),
       'Zim': ('Irk', 'Invader'),
       'Lrrr': ('Omicron Persei 8', 'Emperor')}

       If a key from the keys argument is missing from the dictionary,
       then that row was not found in the table.

   Raises:
       IOError: An error occurred accessing the bigtable.Table object.
   """
   pass


Классы

Классы должны иметь строку документации ниже своего объявления. Если Ваш класс имеет публичные атрибуты, они должны быть документированы тут же в разделе Attributes и следовать тому же стилю форматирования, что и раздел Args.

class SampleClass(object):
   """Summary of class here.

   Longer class information....
   Longer class information....

   Attributes:
       likes_spam: A boolean indicating if we like SPAM or not.
       eggs: An integer count of the eggs we have laid.
   """

   def __init__(self, likes_spam=False):
       """Inits SampleClass with blah."""
       self.likes_spam = likes_spam
       self.eggs = 0

   def public_method(self):
       """Performs operation blah."""


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


Последнее место, которое должны иметь комментарии — это хитрые места в коде. Если Вы хотите пояснить их в Вашем следующем код-ревью, то вы должны прокомментировать их сейчас. Сложные операции, занимающие несколько строк документации перед ее выполнением. Неявные части должны иметь комментарий в конце строки.

# We use a weighted dictionary search to find out where i is in
# the array.  We extrapolate position based on the largest num
# in the array and the array size and then do binary search to
# get the exact number.

if i & (i-1) == 0:        # true iff i is a power of 2


Чтобы улучшить читаемость, такие комменарии должны находиться на расстоянии по меньшей мере 2-х пробелов от кода. С другой стороны, лучше вообще не описывайте код. Преположите, что человек, читающий данный код, знает Python (а не то, что вы пытались делать) лучше, чем Вы.
# BAD COMMENT: Now go through the b array and make sure whenever i occurs
# the next element is i+1


Классы

Если класс не наследуется от каких либо классов, явно наследуйтесь от класса object
Это также касается вложенных классов.

Хорошо:

class SampleClass(object):
     pass

class OuterClass(object):

        class InnerClass(object):
                pass


class ChildClass(ParentClass):
     """Explicitly inherits from another class already."""


Плохо:

class SampleClass:
       pass

    class OuterClass:

       class InnerClass:
           pass


Наследование от класса object необходимо, чтобы позволить свойствам работать правильно, и защитит Ваш код от возможной несовместимости с Python 3000. В нем так же определяются специальные методы, которые реализуют стандартную семантику объекта, например: __new__, __init__, __delattr__, __getattribute__, __setattr__, __hash__, __repr__, и __str__.

Строки

Используйте оператор % для форматирования строк
Используйте оператор % для форматирования строк, даже если все параметры являются строками. Тщательно взвесте использование оператора + взамен оператора %.

Хорошо:

x = a + b
x = '%s, %s!' % (imperative, expletive)
x = 'name: %s; score: %d' % (name, n)


Плохо:

x = '%s%s' % (a, b)  # use + in this case
x = imperative + ', ' + expletive + '!'
x = 'name: ' + name + '; score: ' + str(n)

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

Хорошо:

items = ['<table>']
for last_name, first_name in employee_list:
     items.append('<tr><td>%s, %s</td></tr>' % (last_name, first_name))
items.append('</table>')
employee_table = ''.join(items)

Плохо:

employee_table = '<table>'
for last_name, first_name in employee_list:
       employee_table += '<tr><td>%s, %s</td></tr>' % (last_name, first_name)
employee_table += '</table>'

Используйте “”” для многострочных строк вместо “”. Заметьте, однако, что всегда лучше использовать явное объединение строк, т.к. многострочные строки не продолжаются до конца программы с таким же отступом.

Хорошо:

print ("This is much nicer.\n"
      "Do it this way.\n")

Плохо:

print """This is pretty ugly.
Don't do this.
"""


Файлы и сокеты

Явно закрывайте файлы и сокеты, когда Вы заканчиваете работу с ними
Пренебрежение открытыми файлами, сокетами и другими файлообразными объектами имеет много побочных эффектов, таких как:
  • Они могут потреблять ограниченные системные ресурсы, такие как файловые дескрипторы. Код, который связан со множеством объектов, может приводить к истощению тех ресурсов без пользы, если они не будут возвращены системе после использования.
  • Содержание файлов в открытом виде может препятствовать другим действиям быть произведенными над ними, таким как, например, перемещение или удаление.
  • Файлы и сокеты, которые общедоступны через код, могут быть ненароком прочитаны или записаны после того, как они были логически «закрыты».

Если они реально закрыты, попытка чтения или записи вызовет исключение, тем самым выявляя проблему очень быстро. Более того, файлы и сокеты автоматически закрываются, когда вызывается декструктор объекта, но связывать время жизни объекта с состоянием файла — это плохая практика по следующим причинам:
  • Нет гарантий, что во время выполнения программы будет вызван декструкор объекта. Разные реализации Python используют разные подходы к управлению памятью, такие как отложенная сборка мусора, которая может существенно продлить жизнь «удаленного» объекта.
  • Неожиданные ссылки на файл могут заставить его «жить» дольше, чем мы этого ожидаем (например, стек исключений, глобальные объекты и т.д.)
  • Приоритетный способ управлять файлами — это использование конструкции with.

with open("hello.txt") as hello_file:
    for line in hello_file:
        print line


Подобные циклу for объекты, которые не поддерживают конструкцию with и используют contextlib.closing()

import contextlib

with contextlib.closing(urllib.urlopen("http://www.python.org/")) as front_page:
    for line in front_page:
        print line


Старый код, написанный под Python 2.5, может подключить возможность использования конструкции with при помощи импорта "from __future__ import with_statement".

Комментарий TODO

Используйте комментарий TODO для временного кода, краткосрочной заплатки, либо хорошего, но не идеального решения
Комментарии-TODO должны включать в себя строку TODO в начале каждого комментария, следующую за имменем, электронным адресом или другим идентификатором того, что лучше сможет обеспечить решение проблемы, указанной в скобках. Точка необязательна. Комментарий, объясняющий что там должно происходить, не требуется. Главная цель — это общий формат для TODO, который позволит быстро найти определенного челвоека, который сможет обеспечить более детальное описание проблемы. TODO не является залогом того, что человек решит данную проблему. Таким образом, когда Вы создаете TODO, он почти всегда содержит только Ваше имя.
# TODO(kl@gmail.com): Use a "*" here for string repetition.
# TODO(Zeke) Change this to use relations.
If your TODO is of the form "At a future date do something" make sure that you either include a very specific date ("Fix by November 2009") or a very specific event
("Remove this code when all clients can handle XML responses.").


Оформление импортов

Каждый импорт должен быть на отдельной строке
Хорошо:

import os
import sys

Плохо:

import os, sys


Импорты всегда располагаются в начале файла, сразу после комментариев уровня модуля, строк документации, перед объявлением констант и
объектов уровня модуля. Импорты должны быть сгруппированы в порядке от самых простых до самых сложных:
  • Импорты из стандартной библиотеки
  • Сторонние импорты
  • Импорты из библиотек Вашего приложения

Наряду с группированием импорты должны быть отсортированы лексикографически, нерегистрозависимо, согласно полному пути до каждого модуля.
import foo
from foo import bar
from foo.bar import baz
from foo.bar import Quux
from Foob import ar


Конструкции

В основном только одна конструкция в одной строке
Однако вы можете расположить результат текста на той же строке, на которой у Вас рапологается условие. Но это можно сделать только в том случае, когда все выражение помещается на одной строке. В частности, Вы никогда не сможете это сделать с конструкцией try/except, т.к. try и except не могут находиться в одной строке, и Вам доступно помещение в одну строку только с конструкцией if БЕЗ else.
Хорошо:

if foo: bar(foo)


Плохо:

if foo: bar(foo)
else:   baz(foo)

try:               bar(foo)
except ValueError: baz(foo)

try:
      bar(foo)
except ValueError: baz(foo)


Контроль доступа

Скрытый текст
Если функция-геттер была бы простой, Вы должны были бы использовать общедоступные переменные для функций-геттеров, чтобы избежать
дополнительных расходов ресурсов на внутренние вызовы Python. Когда добавлено много функциональности, вы можете использовать свойства,
дабы следовать целостности интерфейса. С одной стороны, если функция-геттер более сложная, или скорость доступа к переменной очень важна, Вы должны использовать вызовы фукнций(см. следующий раздел гайдлайна), такие как get_foo() и set_foo(). Если поведение позволяет доступ через свойство, то не привязывайте к нему новый геттер. Любой код, который все еще пытается получить доступ к переменной при помощи старого метода, должен явно падать, дабы Вы смогли получить предупреждение о том, что сложность доступа изменилась.

Именование

module_name, package_name
module_name, package_name, ClassName, method_name, ExceptionName, function_name, GLOBAL_CONSTANT_NAME, global_var_name, instance_var_name, function_parameter_name, local_var_name.

Имена, которых следует избегать:
  • Односимвольные имена, исключая счетчики, либо итераторы
  • Минусы в именах модулей и пакетов.
  • Двойные подчеркивания (в начале и конце имен) — зарезервированы для языка.


Конвенция именования
  • «Внутренний» — означает внутренний для модуля, защищенный или приватный класс.
  • Подстановка ведущего подчеркивания (_) поддерживается для защищенных переменных модуля и функций (которые не импортируются при import * from)
  • Подстановка двойного ведущего подчеркивания (__) к имени переменной или метода эффективно делает их приватными для данного класса (использует добавление к имени). Помещение связанных классов и уровней верхнего уровня вместе в модуле. В отличие от Java, не нужно ограничивать себя в создании одного класса в одном модуле.
  • Используйте верблюжью нотацию для именования классов, а нотацию с прописными буквами и подчеркиваниями для имен модулей. Хотя существует много модулей использующих для именования верблюжью нотацию, но так не рекомендуется делать, ведь это может вводить в заблуждение, т.к. модуль называется в честь класса. (погодите, не писал ли я import StringIO или from StringIO import StringIO?)


Стили основаны на рекоммендациях Гвидо:
Тип Внешний Внутренний
Пакеты lower_with_under
Модули lower_with_under _lower_with_under
Классы CapWords _CapWords
Исключения CapWords
Функции lower_with_under() _lower_with_under()
Глобальные/Внутриклассовые константы CAPS_WITH_UNDER _CAPS_WITH_UNDER
Глобальные/Внутриклассовые переменные lower_with_under _lower_with_under
Переменные экземпляра класса lower_with_under _lower_with_under (protected) or __lower_with_under (private)
Имена методов lower_with_under() _lower_with_under() (protected) or __lower_with_under() (private)
Аргументы функций/методов lower_with_under
Локальные переменные lower_with_under


Main

Даже когда файл создавался для того, чтобы быть импортированным..
Даже когда файл создавался для того, чтобы быть импортированным, обычный импорт не должен иметь побочных эффектов в виде исполнения функциональной части скрипта. Основная функциональность должна быть заложена в функции main().
В Python, pychecker, pydoc и юнит тестах требуются импортируемые модули. Ваш код должен всегда проверять if __name__ == '__main__' перед исполнением, что означает, что Ваш модуль не будет полностью исполнен при импортировании его в другую программу.
def main():
      ...

if __name__ == '__main__':
    main()

Весь код верхнего уровня будет исполнен, когда модуль будет импортирован. Будьте осторожны и не вызывайте функции, не создавайте объекта и не проводите другого вида операции, которые не должны будут выполняться, когда файл подвергнется проверке с помощью pychecker или будет собираться документация при помощи pydoc.

Заключительные слова

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

Версия: 2.48
Amit Patel
Antoine Picard
Eugene Jhong
Jeremy Hylton
Matt Smart
Mike Shields


От переводчика


ЧАВО

  • PDF-версия перевода в скором времени будет выложена ссылкой в обоих статьях, так что не промахнетесь:)
  • Нет, я не перевожу комментарии. Я считаю (лично мое мнение), что комментарии в коде должны быть на английском.

Благодарности

Огромное спасибо squaii за ревью и поиск ошибок.

Заключение

Пожалуйста, заклинаю я Вас — пишите порядочный код, господа! Заботьтесь о тех, кто будет поддерживать Ваши труды. Пожалейте их глаза, сэкономьте их силы, подарите им радость жизни, свободной от постоянно больной головы и кругов под глазами. Как известно Вы написавший только что код и Вы через месяц вернувшийся к его поддержке — уже составляете командную разработку, так что не ленитесь писать прозрачно даже тогда, когда Вы один предполагаете поддерживать написанный код. Искореняйте зло, насилие и содомию в среде IT-специалистов (и не только). Всем добра!

P.S.: И помните:

Как Вы думаете, стоит ли переводить статьи по программированию на русский язык?

Проголосовало 717 человек. Воздержался 71 человек.

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

Code : super @Lovesuper
карма
–1,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (52)

  • +9
    Нет, я не перевожу комментарии. Я считаю (лично мое мнение), что комментарии в коде должны быть на английском.
    Абсолютно правильное мнение.
    ps. Спасибо и ждем pdf.
    • 0
      Спасибо!
    • +2
      Вы знаете, я много за свою жизнь видел кода, но мало комментариев на английском, я видел кучу коментариев на языке с английскими корнями, которые при переводе выглядят как «я твой дом труба шатал». Непонятно зачем цепляться за такой таджикоанглийский, лучше уж писать на русском.
      • +3
        Всегда существует вероятность того, что Ваш код будет поддерживать не носитель русского языка. Английский просто универсальнее.
      • +1
        Евгений, вы неоставляете возможность иностранному разработчику поддерживать код. Это может быть офшорная разработка или разработчик-иностранец в вашей компании. Английский в любом его исполнении понимается большинством разработчиков, поэтому «дом труба шатал», лучше чем "ハウスパイプ揺れ".
        • +2
          Скопирует в ГуглТранслейт и получит тот же результат, что я бы написал (а может к тому времени транслейт ещё поумнеет и результат будет лучшем чем на момент написания кодв). Но если у него рядом (или на связи) будет человек, знающий хорошо и русский, и английский, то сможет нормально переписать на английском. А если гугл даст мне английский аналог «дом труда шатал», то я могу его понять (будь английский мой родной) и как «дом трубу шатал» и как «у дома шаталась труба». и как «дом с трубой шатался» и ещё кучей способов.

          Так что лучше писать комментарии на русском «сколько времени» чем на «английском» «how many time». Проверено на работе в трехязычной команде, где лишь два человека хорошо владели двумя языками, причем общий для них был немецкий. Я писал на русском, немец переводил с русского на немецкий и свои комменты на немецком писал, а англичанин с немецкого на английский. переводил. В итоге почти все комменты были переведны с обычного русского и обычного немецкого на английский. но всё это так, без особого напряга, типа встретился коммент и переводят. Патчей только с переводом обычно не было. А собственно предложил такую систему ввести англичанин, как ему надоело узнавать что же мы имели в виду написав «дом труба шатал». :)
      • 0
        Это еще и хорошая прокачка английского, если не практиковаться так и будет разработчик всю жизнь «труба шатал» — я только из-за этого и пишу по-английски комменты.
        И еще есть что-то чуждое в кириллице в коде.
        • +1
          Долго вы уже пишите такие комментарии? Насколько хорошо знаете английский? Можно подумать, английский — это только слова. Языковые конструкции и прочее не прокачать комментариями — поправить-то вас некому.
          • 0
            В таком случае языку нельзя обучиться самостоятельно, если судить по вашей логике: у меня нет преподавателей и носителей языка — т.е. поправить меня некому.
            Можно подумать, английский — это только слова.

            Но и слова тоже. Одними комментариями сыт не будешь, правда: нужны аудио и видео, книги и журналы. Однако, если попытаться перевести сложный коммит, мозг начнет напрягаться — это хорошо, не так ли?
            • 0
              В таком случае языку нельзя обучиться самостоятельно, если судить по вашей логике: у меня нет преподавателей и носителей языка — т.е. поправить меня некому.
              Нет, не правильно. Вы можете взять учебник и выучиться. Только учебник — это методика, там есть последовательность, как выучить язык. Комментарии в коде — не методика изучения языка, максимум — расширение словарного запаса и то до какой-то степени.
              Однако, если попытаться перевести сложный коммит, мозг начнет напрягаться — это хорошо, не так ли?
              Или вы его переведёте неправильно, если его писал неуч, который не отличает «важный» от «импотент».
              • 0
                Нет, не правильно. Вы можете взять учебник и выучиться.
                Надеюсь вы не думаете, что я предлагаю начать изучение английского с написания комментариев в коде?

                максимум — расширение словарного запаса и то до какой-то степени.
                Вы так говорите будто это что-то плохое. Или, грубо говоря, вы со мной согласны, но не согласны? :-)
                Практика — она и есть практика, в ней ошибаются и осознают свои ошибки. Написание писем, комментариев к коду, тикетов в трекере, общение на форуме — практика письменного английского.
                • 0
                  Это если осознаете. Обычно люди не осознают, что они пишут «дом труба шатал». Если каждое слово, вернее каждую грамматическую конструкцию проверяете по справочнику (не забывая про список исключений) — то, да, лучше писать на английском комментарии. Но вряд ли это допустимо в рабочих проектах. Да и в своих тоже уу меня как-то не прижилось — или программировать, или язык изучать.
        • 0
          И еще есть что-то чуждое в кириллице в коде.

          А, по-моему, нормально: github.com/idlesign/pyyaru/blob/master/pyyaru/pyyaru.py %P

          Однако этот пример не говорит о том, что так нужно делать везде, он говорит о том, что нужно понимать целевую аудиторию проекта.
          • 0
            Кстати, в виндоус если не писать насильно print string, а скажем так print (integer, string), в случае кириллицы во втором примере в трейсе будут кракозябры.
            • 0
              Да, в win много интересного, только как это относится к комментариям на русском?
              • 0
                Напрямую :-) Вы пишите комментарии на русском, вы пишите эксепшены на русском, программа падает, я гляжу в консоль и вижу «РЁРёСЂРѕРєР°СЏ …» — я вынужден искать этот участок в коде.
                • 0
                  Неа, вы что-то путаете, я исключения на русском не пишу :)
                  • 0
                    Кхм. Какая разница в мотивах? Я имею ввиду, если вы пишите комментарии по-русски, почему эксепшены по-английски? Комментарии и эксепшены — своего рода синонимы, т.к. и те и другие оставляют подсказки разработчику.
                    • 0
                      А я просто не считаю их синонимами, иначе, встав на этот путь, можно и код объявить синонимом — он тоже подсказка разработчику.

                      Посмотрите на это так: строки документации предназначены тем, кто знакомится с кодом программного продукта, описания в исключениях — тем, кто пользуется программным продуктом.
    • 0
  • +1
    Спасибо! Многое просто повторяет PEP8, но всё равно было любопытно прочитать. Скажите, а в чём смысл использования спойлеров в этой статье?
    • +3
      А Вы попробуйте развернуть все эти спойлеры и посмотрите на бегунок полосы прокрутки Вашего браузера. А если вы с планшета зайдете? Замучаетесь мотать. Мне кажется, это просто забота о людях. Да и вообще — какая-то изюминка сохраняется:)
  • +8
    !#/usr/bin/python не везде работает. Лучше все же #!/usr/bin/env python, имхо
    • 0
      Приведите, пожалуйста, пример. Я просто не встречал…
      • 0
        Arch сейчас поставляется с python 3.x в роли основного интерпретатора python'а. Как следствие, путь /usr/bin/python будет указывать на третью версию. Если Вы всё ещё используете вторую ("~95%" (тут могло быть любой число) серьёзной разработки на python'е), то ваш скрипт вполне может и не поехать. Например из-за print или метаклассов.
      • +3
        FreeBSD — /usr/local/bin/python.
    • +2
      Люто плюсую. Использование прямого пути к интерпретатору ограничивает использование virtualenv.
    • 0
      Или даже /bin/env python
      • 0
        bolk@bolknote ~$ /bin/env
        -bash: /bin/env: No such file or directory
        bolk@bolknote ~$ uname
        Darwin
  • +4
    Используйте оператор % для форматирования строк...

    Заклинаю, используйте метод format().
    • 0
      Да, все правильно, если бы я публиковал своё мнение, я бы так и написал. Хотя бы потому, что это Python 3 compatible:)
      • +1
        Ну так и сделали бы ремарочку от себя.
        • 0
          Дык, не положено! Свое мнение будет в следующем посте;)
          • 0
            Почему не положено? Примечание переводчика сделайте просто.
    • 0
      Да ладно вам. Переход от 2.7 (гляжу на свой проект и говорю честно) к 3.0 будет все равно, что его переписать. Если он вообще когда-нибудь перейдет. В таком ключе format() это все равно что писать на горящий дом. Да и приятнее иногда старый синтаксис: 'Hi, %s!' % username
      А еще вот:
      log.debug('foo: {}'.format(x))
      log.debug('foo: %s', x)
      

      Хотя я понимаю, что это слабый аргумент )
      • 0
        Я не из-за совместимости, я из-за внешнего вида. Когда 3-4 переменных нужно загнать в строку оператор % внешне уже не выглядит привлекательным лично по-моему мнению.
        • +1
          А если 1 переменная (что чаще всего)?
          • 0
            Только единообразие! Только хардкор!
        • 0
          На вкус и цвет :-)
          foo = """Hi, %(user)s…%(message)s"""
          bar = {'user': username…'message': message}
          baz = foo % bar
          

          А вот передать 10 аргументов в format(), чтобы оно свалилось в 5 строчек будет не красиво. Если случай действительно сложный, я использую переменные — код так приятнее.
          • 0
            baz = 'Hi, {user}s…{message}s'.format(user=username, message=message)
            
            • 0
              Я хотел сказать, что если аргументов много лично я предпочитаю разделять код на переменные: обратите внимание на многоточие — в таком случае оба подхода выглядят одинаково хорошо.
              Опять же, лично мне нравится больше старый синтаксис, если аргумент один или их не больше трех, поэтому я и написал «на вкус и цвет».
      • 0
        Это осколок перлосинктасиса. Поэтому его и меняют.
        • 0
          Что странно. При создании Python впитал в себя лучшее из языкостроения тех времен, так зачем от этого отказываться, если это оказалось весьма удобным?
          • +1
            There should be one — and preferably only one — obvious way to do it.
            • 0
              Совсем не это было в обосновании PEP 3101.
              Ну, и речи об отказе от % и замене методом не идёт.
          • 0
            Те времена прошли :)
      • 0
        А чем плохо "%(dict_key_name)s %(dict_key_name2)s %(dict_key_name3)s" % dict?
        • 0
          Да ни чем. Как видно из моего комментария, старый синтаксис мне порой нравится больше.
  • 0
    Ребят, понимаю что оффтопик, начал учить Питон 3.3 для научных целей (анализ соц. сетей и обработка естественного языка).
    Подскажите основные ресурсы по Питону на русском, именно форумы чтобы спрашивать, набрал в гугле «python русское сообщество» и ВСЕ первые ссылки это заброшенные форумы, последнее сообщение в которых хорошо если несколько месяцев назад. Самый актуальный это пока vingrad — но и на нем не так чтоб много народу.
    Английский знаю и пользуюсь преимущественно pyvideo.org www.codecademy.com/ru/tracks/python и stackoverflow.
  • +1
    Где-же pdf, обновляю страничку каждый день :)
    • 0
      Прошу прощения, Уважаемый. Дипломом был занят:) Сделаю на днях!
  • 0
    Максимальная длина строки — 80 символов

    У них мониторы 1024х768 что ли? Почему не 120 символов?

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