Стиль кода для отступа многострочного оператора "if"? [дубликат]

этот вопрос уже есть ответ здесь:

при отступе долго, если условия, вы обычно делаете что-то вроде этого (на самом деле, PyDev отступы, как это):

if (collResv.repeatability is None or
    collResv.somethingElse):
    collResv.rejected = True
    collResv.rejectCompletely()

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

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

if (collResv.repeatability is None or
        collResv.somethingElse):
    collResv.rejected = True
    collResv.rejectCompletely()

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

if (collResv.repeatability is None or
  collResv.somethingElse):
    collResv.rejected = True
    collResv.rejectCompletely()

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


Итак, мой главный вопрос: есть ли предлагаемый стиль отступа для случаев, подобных тому, который не требует чрезмерно длинных строк (т. е. однострочного условия)? Если нет, то что делать вы предпочитаю для таких случаев?

9 ответов


это косвенный ответ-не отвечая на вопрос стиля напрямую, но это практический ответ в целом, поэтому стоит упомянуть.

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

  • не оберните код в 80 столбцов. Совет PEP-8 по этому вопросу древний и вредный; мы давно прошли Дни терминалов 80x25 и редакторов, которые не могут разумно обрабатывать упаковку. 100 столбцов в порядке, и 120 обычно также приемлемо.
  • если условия становятся настолько длинными, что им все еще нужно обернуть, обычно разумно переместить некоторую логику из условного и в отдельное выражение. Это также помогает читаемости.

Grepping через мои последние проекты, вокруг 12kloc, есть только один условный достаточно долго, что он должен быть завернут; проблема просто очень редко возникает. Если вам нужно это сделать, то, как говорит носкло, отступ отдельно-как вы заметили, отступ на тот же уровень, что и блок под ним, запутан и трудно читается.


часто я работаю над этой проблемой, вычисляя условие в собственном утверждении:

condition = (collResv.repeatability is None or
             collResv.somethingElse)
if condition:
    collResv.rejected = True
    collResv.rejectCompletely()

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


вот что я делаю:

if (collResv.repeatability is None or
        collResv.somethingElse):
    collResv.rejected = True
    collResv.rejectCompletely()

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

Я рекомендую поместить логический оператор в ту же строку, что и условие, которое он добавляет к оператору if.

это на мой взгляд, лучше

if (None == foo
        and None == bar
        or None == foo_bar):

чем этот:

if (None == foo and
        None == bar or
        None == foo_bar):

PEP-8 на самом деле кажется противоречивым здесь. В то время как пример в разделе "максимальная длина строки" показывает использование круглых скобок и стандартного 4-символьного отступа, раздел "отступ" говорит в отношении объявлений функций: "дальнейший отступ должен использоваться, чтобы четко различать себя как линию продолжения.". Я не понимаю, почему это будет ограничено только "def", а не"if".


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

if (collResv.repeatability is None or
                          collResv.somethingElse):
    collResv.rejected = True
    collResv.rejectCompletely()

PEP-8 советую прямо здесь.

http://www.python.org/dev/peps/pep-0008/#indentation

ниже кода рекомендуется

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

# More indentation included to distinguish this from the rest.
def long_function_name(
        var_one, var_two, var_three,
        var_four):
    print(var_one)

ниже кода не рекомендуется

# Arguments on first line forbidden when not using vertical alignment
foo = long_function_name(var_one, var_two,
    var_three, var_four)

# Further indentation required as indentation is not distinguishable
def long_function_name(
    var_one, var_two, var_three,
    var_four):
    print(var_one)

Pep-8 рекомендует способ отступа исходного примера.

теперь, если вы готовы летать перед лицом о, так священных руководств стиля :-) вы можете переместить оператор на следующую строку:

if (collResv.repeatability is None
    or collResv.somethingElse):
    collResv.rejected = True
    collResv.rejectCompletely()

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


в таком случае, я бы просто сделать:

if (collResv.repeatability is None or
    collResv.somethingElse):
    # do:
    collResv.rejected = True
    collResv.rejectCompletely()

вариант, который я иногда использую (хотя я не полностью продан на его читаемость):

if (collResv.repeatability is None or
    collResv.somethingElse
):
    collResv.rejected = True
    collResv.rejectCompletely()

возможно, это было бы более читаемым таким образом:

if (
collResv.repeatability is None or
collResv.somethingElse
):
    collResv.rejected = True
    collResv.rejectCompletely()