Подтвердить что ты не робот

Код-стиль для отмены многострочного выражения "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, и, кроме того, он выглядит неправильным, поскольку вторая строка имеет меньше отступов, чем начало условия в первой строке.


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

4b9b3361

Ответ 1

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

Мне очень редко приходится писать многострочные условные обозначения. Для этого есть два фактора:

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

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

Ответ 2

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

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

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

Ответ 3

Это то, что я делаю:

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

Ответ 4

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

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

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

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

чем это:

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

Ответ 5

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

Ответ 6

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

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)

Ответ 7

Pep-8 рекомендует, как вы отступали от вашего оригинального примера.

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

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

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

Ответ 8

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

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

Ответ 9

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

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()