web-dev-qa-db-ja.com

複数行の 'if'ステートメントのインデントのコードスタイル?

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

2行目は1行目よりもはるかにインデントされているため、これはかなり一貫していないように見えますが、読みやすいです。

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

これも最初の例より読みやすくなっていますが、インデントは4の倍数ではなくなり、2行目は1行目の条件の先頭よりもインデントが少ないため、見栄えが悪くなっています。


だから、私の主な質問は:過度に長い行を必要としないようなケース(つまり、単一行の条件)に推奨されるインデントスタイルはありますか?そうでない場合、そのような場合にあなたは何を好みますか?

35
ThiefMaster

これは間接的な回答です。スタイルの質問に直接回答するわけではありませんが、これは一般的な実用的な回答なので、言及する価値があります。

複数行の条件文を記述する必要があることは非常にまれです。これには2つの要因があります。

  • 80列でコードを折り返さないでください。この問題に関するPEP-8のアドバイスは古くて有害です。ラッピングをうまく処理できない80x25端末とエディターの時代はもう過ぎ去っています。 100列で十分ですが、通常は120列でもかまいません。
  • 条件が長くなりすぎてラップする必要がある場合は、通常、ロジックの一部を条件から別の式に移動するのが妥当です。これは読みやすさにも役立ちます。

私の最近のプロジェクト(12klocあたり)を概観すると、ラップする必要があるのに十分長い条件が1つだけあります。この問題が発生することはほとんどありません。これを行う必要がある場合は、noskloが言うように、個別にインデントします。気づいたように、その下のブロックと同じレベルにインデントすると、混乱して読みにくくなります。

9
Glenn Maynard

多くの場合、自分のステートメントで条件を計算することにより、この問題を回避します。

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

ただし、特定の例のようにまだ比較的短い条件の場合はnoskloの解決策を探します-ここで使用される追加のステートメントは、さらに長い条件式に適しています。

23
Oben Sonne

これが私がすることです:

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

ここでのすべての以前の提案の1つの問題は、後続の条件の論理演算子が前の行に配置されることです。イモ、それはそれを読みにくくします。

Ifステートメントに追加する条件と同じ行に論理演算子を置くことをお勧めします。

これは私の意見では、より良いです

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

これより:

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

PEP-8は実際にはここでは矛盾しているようです。 「最大行長」の例では括弧と標準の4文字のインデントの使用を示していますが、「インデント」セクションでは、関数宣言に関して、「継続インデントとして明確に区別するために、さらにインデントを使用する必要があります。 」これが「def」だけに制限され、「if」に制限されない理由はわかりません。

3
mcote

私はこのようにします。混乱しないように、字下げは遠くにしてください。

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)
3
ronak

そのような場合、私は単にそうします:

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

Pep-8は、元の例をインデントする方法を推奨しています。

さあ、神聖なスタイルガイドの前を飛んで進んでよければ:-)次の行にオペレーターを移動できます。

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

私はこれのファンではありません。元の構文はかなり読みやすいので、インデントや改行をあまり気にせずに済みます。

0
stderr