Правильный стиль для разрывов строк при цепочке методов в Python

У меня есть такой код. Должен ли перерыв происходить до месячных или после?

# before
my_var = somethinglikethis.where(we=do_things).where(we=domore).where(we=everdomore)

# this way
my_var = somethinglikethis.where(we=do_things) \
                          .where(we=domore) \
                          .where(we=everdomore)

# or this way
my_var = somethinglikethis.where(we=do_things). \
                           where(we=domore). \
                           where(we=everdomore)

person JiminyCricket    schedule 30.10.2011    source источник


Ответы (5)


PEP 8 рекомендует использовать круглые скобки, чтобы вам не нужно было \, и осторожно предлагает разрывать перед бинарными операторами, а не после них. Таким образом, предпочтительный способ форматирования кода выглядит следующим образом:

my_var = (somethinglikethis
          .where(we=do_things)
          .where(we=domore)
          .where(we=everdomore))

Два соответствующих отрывка — это один из Максимальная длина строки раздел:

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

... и весь Следует ли разрывать строку до или после бинарного оператора? section:

Должна ли строка разрываться до или после бинарного оператора?

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

# No: operators sit far away from their operands
income = (gross_wages +
          taxable_interest +
          (dividends - qualified_dividends) -
          ira_deduction -
          student_loan_interest)

Чтобы решить эту проблему удобочитаемости, математики и их издатели следуют противоположному соглашению. Дональд Кнут объясняет традиционное правило в своей серии статей Компьютеры и набор текста: «Хотя формулы внутри абзаца всегда прерываются после бинарных операций и отношений, отображаемые формулы всегда прерываются перед бинарными операциями».

Следование традиции из математики обычно приводит к более читабельному коду:

# Yes: easy to match operators with operands
income = (gross_wages
          + taxable_interest
          + (dividends - qualified_dividends)
          - ira_deduction
          - student_loan_interest)

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

Обратите внимание, что, как указано в приведенной выше цитате, PEP 8 используется, чтобы дать противоположный совет о том, где прерывать оператор, приведенный ниже для потомков:

Предпочтительным способом переноса длинных строк является использование подразумеваемого 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 -- values are %s, %s" %
                             (width, height))
        Blob.__init__(self, width, height,
                      color, emphasis, highlight)
person Bastien Léonard    schedule 30.10.2011
comment
Рекомендация разрыва после оператора имеет смысл для таких операторов, как + и или, вокруг которых обычно есть пробелы. В случае . оператора, вероятно, имеет смысл выполнить break-before-operator. В противном случае наш опыт работы с английским языком заставляет нас мысленно читать конечную точку как точку, а не как поиск метода/атрибута. - person Raymond Hettinger; 30.10.2011
comment
Обратите внимание, что Rectangle пример из PEP8 был обновлен в 2013 году с новым многострочным отступом. (Я пытался отредактировать ответ, но это не прошло.) - person duozmo; 14.02.2016

PEP 8 говорит, что предпочтительнее прерывание перед оператором:

Дональд Кнут объясняет традиционное правило в своей серии «Компьютеры и набор текста»: «Хотя формулы внутри абзаца всегда прерываются после бинарных операций и отношений, отображаемые формулы всегда прерываются перед бинарными операциями».

...

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

https://www.python.org/dev/peps/pep-0008/#should-a-line-break-before-or-after-a-binary-operator

person Neapolitan    schedule 09.05.2016
comment
Поскольку принятый ответ был обновлен, чтобы ассимилировать все, что содержалось в этом ответе, возможно, имеет смысл удалить этот ответ? Поскольку у него больше 3 баллов, вы сохраните свою репутацию. - person Mark Amery; 07.01.2018

Делайте то, что работает.

Кроме того, ознакомьтесь с этим техническим описанием мифов об отступах в Python. Это можно найти здесь.

Он начинается с:

Пробелы важны в исходном коде Python.

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

Надеюсь, это поможет.

person Mr_Spock    schedule 30.10.2011
comment
-1; Вы также можете вставлять пустые строки, которые ничего не содержат (или содержат только произвольные пробелы) в любом месте. явно не соответствует действительности. print('Hello, World') не будет работать, если вы поместите новую строку между print и открывающей скобкой. Я не могу придумать ни одного языка, в котором пробелы не имеют значения и их можно использовать по своему усмотрению, это верное утверждение; return1 в функции обычно является синтаксической ошибкой, а return 1 допустимо. - person Mark Amery; 13.12.2017

FWIW, autopep8 (с флагом --aggressive) создал это из исходного кода:

my_var = somethinglikethis.where(
    we=do_things).where(
    we=domore).where(
    we=everdomore)

Но я согласен - решение Бастьена более элегантно.

person Amanda    schedule 18.02.2014

Там действительно нет никаких неправильных путей. Все перечисленные вами будут работать одинаково.

person D3_JMultiply    schedule 30.10.2011