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

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

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

Пример хорошего отступа для длинных строк:

👍
class ClassName(ThisClasss,
                HasLotOfBaseClasses,
                SoIndentIsDone,
                WithAlignToBracket,
                ToMakeDefinitionWellVisible):
    """Example with my best indentation."""
example_list = [
        'it',
        'is',
        'nice',
        'to',
        'have',
        'vertical',
        'lit',
    ]
    another_list = [
        'content',
        'of',
        'vertical',
        'lists',
        'is',
        'well',
        'presented',
    ]
def __init__(self,
                 also_this_method,
                 has_lot_of_arguments,
                 and_to_keep_it_well_readable,
                 we_indent_it_also_to_bracket):
        """Proper indentation."""
        but_if_we_wrap_long_line = we_are_doing_it_with_tab_index(
            here_will_be_explained + why_it_has_sense)

Чтобы проиллюстрировать преимущества первого блока кода, посмотрите следующие примеры:

👎
class ClassName(
        ThisClasss,
        HasLotOfBaseClasses,
        SoIndentIsDone,
        WithAlignToBracket,
        ToMakeDefinitionWellVisible,):
    """Example with my best indentation."""
example_list = ['it',
                    'is',
                    'nice',
                    'to',
                    'have',
                    'vertical',
                    'list']
    another_example_list = ['content',
                            'of',
                            'vertical',
                            'lists',
                            'is',
                            'well',
                            'presented',
                            ]
def __init__(
            self,
            also_this_method,
            has_lot_of_arguments,
            and_to_keep_it_well_readable,
            we_indent_it_also_to_bracket,
            ):
        """Proper indentation."""
        wrap_long_line = align_to_bracket(below_will_be_explained + 
                                          why_it_has_no_sense)

Это чувство: приведенный выше пример выглядит хуже, даже если он все еще совместим с PEP8:

  1. Определение функции не так однозначно.
  2. Определения списка не умещаются на вертикальной линии.
  3. Обертывание кода тела функции в скобки часто приводит к пустой трате места.
  4. Иногда скобка находится слишком далеко, и ее нужно отформатировать с помощью вкладок, что приводит к потере единообразия стиля форматирования.

Проведите две линии, показывающие еще один риск. Представьте, что функция we_are_align_to_bracket требует некоторой перезаписи и, наконец, меняет свое имя на просто align_to_bracket. Мы используем для этого утилиту перезаписи в PyCharm, поэтому она автоматически заменяет это имя использования функции. Тогда мы получили:

👎
if_we_wrap_long_line = align_to_bracket(below_will_be_explained + 
                                 why_it_has_no_sense)

Код потерял форматирование! Итак, как это работает в «хорошем» случае - с вкладками?

👍
but_if_we_wrap_long_line = doing_it_with_tab_index(
     below_will_be_explained + why_it_has_sense_to_do_this_this_way)

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

👍
but_if_we_wrap_long_line = doing_it_with_tab_index(
            below_will_be_explained,
            why_it_has_sense_to_do_this_this_way)
            
        but_if_we_wrap_long_line = doing_it_with_tab_index(
            below_will_be_explained,
            or_this_way,
        )

Вы говорите, что мы можем исправить форматирование в коде. Да! Вероятно, большинство инструментов покажут вам, что будет изменено (может быть разным: кто-то все еще может использовать shell pipe), но это может привести к множеству исправлений, которые нужно сделать. Так зачем же делать жизнь уродливее и сложнее?

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

Мы можем исправить форматирование в коде, - говорите вы. Да! Вероятно, большинство инструментов покажут вам, что будет изменено (может быть разным: кто-то все еще может использовать shell pipe), но это может привести к множеству исправлений, которые нужно сделать. Так почему же жизнь становится уродливее и сложнее?