Комментарии не должны быть необязательными*

Я твердо верю в:

Только дурак имеет дело с абсолютами

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

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

Комментарии занимают процессорное время

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

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

Что такое хороший комментарий

Классический парафраз «Опишите свое намерение, а не свою логику». всегда полезно.

def unpack(results: dict) -> pollkit.QueryResult:
    """
    Unpack provided results, typically coming from the
    web API or data cache. There are a number of checks
    done in this function, each of them documented below
    with a "# Check: ..."
    .. tip::
        This will always force file-path fields into unix
        style slashes. ``file://`` will also be stripped if
        found.
    :raise: :ref:`pollkit.QueryResult.Invalid`` if the
        data isn't aligned. Best to use try/except for
        anything that doesn't need to succeed.
    :param results: ``dict``
    :return: :ref:`pollkit.QueryResult`
    """
    for key, val in results.items():
        # ...

Это много документации только для одной функции, но теперь мы всегда можем вернуться, и мы никогда не наткнемся на «подвох» обработки пути.

Кстати, мне очень нравится документация в стиле сфинкс. Я даже использую его для некоторых своих проектов на C++.

Действие на расстоянии

Обычно полезно передавать информацию о соединении для событий, которые не очевидны при чтении.

# Note: This will trigger an update on the UI
#       via the pollkit.add_connection(...)
pollkit.fetch_data()

Быть многословным (до определенной степени)

Подробное описание того, что что-то делает, редко бывает плохим.

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

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

Будьте точны

  • Работайте над своей терминологией и придерживайтесь ее при документировании.
  • Создайте глоссарий для всего, что относится к вашему коду

Будьте настойчивы

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

Практика

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

Наконец, добавьте примеры!

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

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

def unpack(results: dict) -> pollkit.QueryResult:
    """
    ...
    .. code-block:: python
        raw = pollkit.fetch_data()
        try:
            results = unpack(raw)
        except pollkit.QueryResult.Invalid as err:
            interface.push_error(err)
        else:
            interface.merge_result(results)

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