Код-стиль для отмены многострочного выражения "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, и, кроме того, он выглядит неправильным, поскольку вторая строка имеет меньше отступов, чем начало условия в первой строке.
Итак, мой главный вопрос: есть ли предлагаемый стиль отступов для таких случаев, которые не требуют чрезмерно длинных строк (т.е. однострочное условие)?
Если нет, что вы предпочитаете для подобных случаев?
Ответы
Ответ 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()