'if'ステートメントで複数行の条件をスタイリングしますか?[閉まっている]


674

ifsの長い条件を数行に分割することがあります。これを行う最も明白な方法は次のとおりです。

  if (cond1 == 'val1' and cond2 == 'val2' and
      cond3 == 'val3' and cond4 == 'val4'):
      do_something

アクションは条件に溶け込むため、視覚的にはあまり魅力的ではありません。ただし、これは4つのスペースの正しいPythonインデントを使用する自然な方法です。

今のところ私が使用しています:

  if (    cond1 == 'val1' and cond2 == 'val2' and
          cond3 == 'val3' and cond4 == 'val4'):
      do_something

しかし、これはあまりきれいではありません。:-)

別の方法をお勧めできますか?


2
お使いのエディタが使用している場合pep8について警告したときに検出するために、PythonパッケージをPEP8の違反、あなたはどちらかを無効E125エラーを持っているか、どの満たすフォーマットする解決策見つけることができますpep8パッケージの基準を。pep8パッケージの問題#126は、厳密にPEP8仕様に従うようにパッケージを固定についてです。この問題の議論には、ここでも見られるいくつかのスタイルの提案が含まれています。
akaihola 2013年

1
最初の例では、pep8は「次の論理行と同じインデントで視覚的にインデントされたE129」をスローすることに注意してください。
テイラーエドミストン

この質問は非常に古く、多くの意見がありますが、明確に意見に基づいています。「あまり魅力的ではない」「非常にきれいではない」という言葉は、正しいと思われる答えが質問者の美的好み(すなわち意見)に最もよく一致するものであるという基準を示しています。まったく同じ質問をして、それは重複ではないと主張することもできます。これは、私の美的趣味が異なるとみなし、別の「正しい」答えを導くからです。
Z4層

@ Z4-tier:はい、それは意見に基づいています。しかし、それは12年前に尋ねられました。SOは当時は別の優しい場所でした。最近、SOの基準が変更されて以来、反対票が蓄積されています。それでも、1分を超えて表示されているため、世界中で害を及ぼすよりも良い結果が得られることを願っています。今日、同じ質問について疑問を抱いている人たちがいることは間違いありません。それをグーグルで調べ、この議論に着手し、彼らの思考を調整するのに役立つことがわかりました。選ばれるいくつかの非常に投票された答えがあります。
Eli Bendersky

@EliBenderskyは完全に同意します。それは、SOが進行中のアイデンティティの危機のようなものです。それは明らかに「ルール」に適合しませんが(有効な回答の数はそれの証拠です)、それが価値を追加するのと同じくらい明白です。すべてが同じであるため、コーディングスタイルについて明確で合理的な見解を示した誰かと協力したいと考えています。
Z4層

回答:


747

2番目の条件行で4つのスペースを使用する必要はありません。多分使用:

if (cond1 == 'val1' and cond2 == 'val2' and 
       cond3 == 'val3' and cond4 == 'val4'):
    do_something

また、ホワイトスペースはあなたが思っているよりも柔軟であることを忘れないでください:

if (   
       cond1 == 'val1' and cond2 == 'val2' and 
       cond3 == 'val3' and cond4 == 'val4'
   ):
    do_something
if    (cond1 == 'val1' and cond2 == 'val2' and 
       cond3 == 'val3' and cond4 == 'val4'):
    do_something

どちらもかなり醜いです。

ブラケットを失うかもしれません(スタイルガイドはこれを推奨しません)?

if cond1 == 'val1' and cond2 == 'val2' and \
   cond3 == 'val3' and cond4 == 'val4':
    do_something

これにより、少なくともいくつかの違いが生まれます。

あるいは:

if cond1 == 'val1' and cond2 == 'val2' and \
                       cond3 == 'val3' and \
                       cond4 == 'val4':
    do_something

私は好きだと思います:

if cond1 == 'val1' and \
   cond2 == 'val2' and \
   cond3 == 'val3' and \
   cond4 == 'val4':
    do_something

(2010年以降)ブラケットの使用を推奨するスタイルガイドを次に示します。


45
末尾の\ソリューションはPEP 8で推奨されていないことに注意してください。1つの理由は、スペースが誤って\の後に追加された場合、エディターに表示されず、コードが構文的に正しくなくなるためです。
Eric O Lebigot、2014年

14
これは誤りです。スタイルガイドには、「長い行は括弧で式を囲むことにより複数行に分割できます。これらは、行の継続にバックスラッシュを使用するよりも優先して使用する必要があります。」これはここにあります:python.org/dev/peps/pep-0008/#maximum-line-length
joshcartme

8
@joshcartme PEPはhg.python.org/peps/rev/7a48207aaab6でバックスラッシュを明示的に阻止するように変更されました。答えを更新します。
ハーレーホルコム2013年

3
おかげで、現在は推奨されていないため、例も更新することをお勧めします。私はこれを自分で理解しようとしましたが、あなたの答えとスタイルガイド(したがって私のコメント)の不一致に混乱しました。私はただのんびりするつもりではありませんでした。
joshcartme 2013年

3
PEP 8は、andとの後のブレークを阻止するようになりifました。
virtualxtc 2018

124

単純なANDまたはORの縮退したケースでは、次の方法を使用しました。

if all( [cond1 == 'val1', cond2 == 'val2', cond3 == 'val3', cond4 == 'val4'] ):

if any( [cond1 == 'val1', cond2 == 'val2', cond3 == 'val3', cond4 == 'val4'] ):

それはいくつかのキャラクターを剃り、状態に微妙なものがないことを明らかにします。


4
これは興味深いアプローチです。ただし、長い条件の問題には対応していません
Eli Bendersky、2008年

20
短絡を気にしなくても大丈夫です。
コンスタンティン

63
shortcirtuitingは常に高速であるとは限りません。良いコーディング方法ではありませんが、次のような既存のコードがある場合がありますif destroy_world and DestroyTheWorld() == world_is_destroyed: ...。素晴らしい、今あなたは偶然に世界を破壊しました。なんてことするんですか?
アーロン

3
これには非常に多くの賛成票があることに驚いています。この回答は、複数行の条件文のスタイル設定に関する元の質問を完全に無視しています。
Przemek D

2
この表現は怠惰ではありません。したがって、いくつかの保護条件の後に障害が発生する可能性がある場合は、同等ではありません。
eugene-bright

56

誰かがここで垂直空白の使用を擁護しなければなりません!:)

if (     cond1 == val1
     and cond2 == val2
     and cond3 == val3
   ):
    do_stuff()

これにより、各状態が明確に表示されます。また、より複雑な条件をより明確に表現できます。

if (    cond1 == val1
     or 
        (     cond2_1 == val2_1
          and cond2_2 >= val2_2
          and cond2_3 != bad2_3
        )
   ):
    do_more_stuff()

はい、わかりやすくするために、垂直方向の不動産を少しトレードオフしています。IMOの価値は十分にあります。


19
これは美しくも、PEP8互換でもないようです。PEP8は、2項演算子(andおよびor)を回避するための好ましい場所は、演算子の前ではなく、演算子のにあると述べています。
Chris Medrela 2013年

7
@ChristopherMedrelaそれはその背後にある理論的根拠を教えていますか?論理演算子の前に改行を置く方がずっと明確だと思う
ノリルテンペスト2014

4
opreratorを最初に置くことは、ノードの世界ではかなり一般的です。理論的根拠は、少なくとも西洋の文化では、左側のものを右側のものよりもはるかに速く気づき、読むことです。JavaScriptで非常に有効であり、カンマを忘れるとサイレントエラーが発生する可能性があります。
tomekwi 2014年

11
これを行わないでください。それだけでなくPEP8、連鎖している論理演算を特定することが難しくなります。コードレビューを通じて私のデスクに来たら、私はこれをばかげたでしょう。
ウルダ

11
PEP8の現在のバージョンで、2項演算子の前または後のいずれかでブレークすることは許容できると見なされており、演算子が新しいコードに適していると見なされる前に中断されます。
Soren Bjornstad 2016

31

非常に大きなif条件がある場合、このスタイルを好みます。

if (
    expr1
    and (expr2 or expr3)
    and hasattr(thingy1, '__eq__')
    or status=="HappyTimes"
):
    do_stuff()
else:
    do_other_stuff()

2
+1を使用すると、インデントを追跡して追跡できます。私はpythonが好きでそれをたくさん使用しますが、インデントを強制されて常にイライラします。マルチラインは、うまくいっていても、美学を本当に壊してしまいます。
マイティパイル2013

4
行の先頭にandand or演算子があると、PEP 0008に違反することに注意してください。これは、「2項演算子を回避するための推奨される場所は、演算子の前ではなく、演算子の後です」と述べています。。私はif条件を本文から分離するために、閉じ括弧とコロンを自分の行に置くのが好きです(そして、PEP-0008準拠のためにブール演算子を行の最後に置いたままこれを行うことは完全に可能です)。
マークアメリー2015

8
2016年現在:For decades the recommended style was to break after binary operators. But this can hurt readability in two ways... In Python code, it is permissible to break before or after a binary operator, as long as the convention is consistent locally. For new code Knuth's style is suggested.(Knuthのスタイルは演算子で行を開始することです)。
カウベルト2018年

27

これが私の個人的な見解です:長い条件は(私の考えでは)ブール値を返す関数/メソッドにリファクタリングすることを示唆するコードのにおいです。例えば:

def is_action__required(...):
    return (cond1 == 'val1' and cond2 == 'val2'
            and cond3 == 'val3' and cond4 == 'val4')

さて、複数行の条件を適切に表示する方法を見つけた場合、おそらくそれらを持っていることに満足し、リファクタリングをスキップします。

一方、それらに私の美的感覚を混乱させることは、リファクタリングのインセンティブとして機能します。

したがって、私の結論は、複数の回線状態は醜く見えるはずであり、これはそれらを回避する動機です。


23

これはそれほど改善されませんが...

allCondsAreOK = (cond1 == 'val1' and cond2 == 'val2' and
                 cond3 == 'val3' and cond4 == 'val4')

if allCondsAreOK:
   do_something

1
興味深い代替案。しかし、2つの余分な行:-)
Eli Bendersky 2008年

反復ループで実際にはうまく機能しないでしょう。何かを行う関数では機能しません...そして公平に言えば、醜い
Mez

9
ブライアン、私は部分的に同意しません。計算の中間結果に変数を使用すると、コードを理解しやすくなり、コンパイル済み言語ではパフォーマンスに影響を与えません。おそらくPythonで実行されますが、パフォーマンスがそれほど重要である場合は、Pythonをまったく使用しません。
Mark Ba​​ker、

1
@MarkBaker私はMartin Fowlersの「リファクタリング」を読むまで、あなたが書いたものに同意していました。彼は、そのような中間変数が利益よりも害を引き起こすという優れた議論を提供します。それらはその後のリファクタリングを阻害します。それらなしで行うと、より機能的なプログラミングスタイルにつながり、リファクタリングに役立ちます。これは私を驚かせましたが、私は彼が正しいと信じており、それ以来、私のようなコードからこのような不要な中間体を排除するために努力しました-たとえそれらが複数回使用されたとしても。
ジョナサンハートレー

2
いいけど、なんでキャメルケース?!:)
Leonid Shvechikov 2013年

19

andキーワードを2行目に移動し、4つではなく2つのスペースを含む条件を含むすべての行をインデントすることをお勧めします。

if (cond1 == 'val1' and cond2 == 'val2'
  and cond3 == 'val3' and cond4 == 'val4'):
    do_something

これが、コードでこの問題を解決する方法です。行の最初の単語としてキーワードを使用すると、条件がより読みやすくなり、スペースの数を減らすと、条件とアクションがさらに区別されます。


9
私はGriesまたはDjikstraのどこかで、論理演算子を行の先頭に置くことで(もっと見やすくなるように)助けたと書いています。そして私はそれを90年代からやっています。そしてそれは役立ちます。
S.Lott、2008年

7
スタイルガイドでは、行の最後に条件を置くことをお勧めしています。
Harley Holcombe

3
これについては私が同意したことはありませんが、そうです。結局のところ、それは単なるガイドです。
DzinX 2008年

8
PEP8 は、行の最後に条件を置くことを推奨しなくなりました。
Soren Bjornstad 2016

13

PEP 0008(Pythonの公式スタイルガイド)を引用する価値があるようです。それは、この問題について適度な長さでコメントしているためです。

- ifステートメントの条件部分が、複数行にまたがって書き込めるほど長い場合、2文字のキーワード(つまりif)と単一のスペース、および左括弧を組み合わせると、自然な4-複数行条件付きの後続行のスペースインデント。これにより、if-statement 内にネストされたインデントされたコードスイートとの視覚的な競合が発生する可能性があり、これも当然4つのスペースにインデントされます。このPEPは、このような条件付き行をif-statement 内のネストされたスイートからさらに視覚的に区別する方法(またはその方法)について明確な立場をとりません。この状況で受け入れられるオプションには、以下が含まれますが、これらに限定されません。

# No extra indentation.
if (this_is_one_thing and
    that_is_another_thing):
    do_something()

# Add a comment, which will provide some distinction in editors
# supporting syntax highlighting.
if (this_is_one_thing and
    that_is_another_thing):
    # Since both conditions are true, we can frobnicate.
    do_something()

# Add some extra indentation on the conditional continuation line.
if (this_is_one_thing
        and that_is_another_thing):
    do_something()

上記の引用の「に限定されない」に注意してください。スタイルガイドで提案されているアプローチのほかに、この質問に対する他の回答で提案されているアプローチのいくつかも受け入れられます。


PEP8の場合は+1。これは(実際に言えば)公式のPythonスタイルガイドであるため、受け入れられるべきです。
マイケル-クレイシャーキーはどこですか

2
また強調する価値があります。PEP8は、そのような条件付き行をifステートメント内のネストされたスイートからさらに視覚的に区別する方法(またはかどうか)について明確な立場を取りません。この状況で受け入れられるオプションには、以下が含まれますが、これらに限定されません。...(省略) したがって、議論をやめて、好きなものを使ってください。
RayLuo 2016

7

これが私がやっていることです。 "all"と "any"はイテラブルを受け入れるので、長い条件をリストに入れて "all"に処理を任せることを覚えておいてください。

condition = [cond1 == 'val1', cond2 == 'val2', cond3 == 'val3', cond4 == 'val4']

if all(condition):
   do_something

4

私の優先する解決策が見当たらないことに驚いています。

if (cond1 == 'val1' and cond2 == 'val2'
    and cond3 == 'val3' and cond4 == 'val4'):
    do_something

andはキーワードなので、私のエディタによって強調表示され、その下のdo_somethingとは十分に異なって見えます。


しかし、継続行は次の論理行と区別されません...
Chris Medrela 2013年

1
これはPEP 0008違反であることに注意してください(「2項演算子を回避するための好ましい場所は、演算子の前ではなく、演算子の後です)。もちろん、気にするかどうかはあなた次第です。
マークアメリー2015

1
ちなみに、これはもはや私の好ましい解決策ではありません。;)
Marius Gedminas

4

@krawyotiの発言に加えて...長い条件は、読みにくく、理解しにくいためにおいがします。関数または変数を使用すると、コードがより明確になります。Pythonでは、垂直スペースを使用し、括弧を囲み、論理演算子を各行の先頭に配置して、式が「浮動」に見えないようにします。

conditions_met = (
    cond1 == 'val1' 
    and cond2 == 'val2' 
    and cond3 == 'val3' 
    and cond4 == 'val4'
    )
if conditions_met:
    do_something

whileループのように条件を複数回評価する必要がある場合は、ローカル関数を使用するのが最適です。


1
これに加えて、追加の変数を作成するのではなく、関数またはラムダを宣言してtrueを返すことができます。
Techdragon 2013

@Techdragon条件が別の場所にある場合は、条件をラムダブロックに入れると、ラムダブロックに名前を付けて、後でif条件で参照できるようにする必要があります。ラムダに名前を付ける場合、なぜそれが通常の関数ではなく、なぜそうなるのでしょうか。私は個人的には、このブール式の削減を気に入っています。
スリカディミセッティ2013

プログラムの制御フローを理解するためにスキミングする際に、可読性の向上とメンタルダイジェストの容易さの両方を実現するために、ほとんどの場合、通常は関数を使用するのはそのためです。私はラムダについて言及し、人々が特にスペースを意識している場合に「より小さな」オプションも確実に存在するようにします。
Techdragon

4

個人的には、長いif文に意味を付けたいと思います。適切な例を見つけるためにコードを検索する必要がありますが、ここで頭に浮かぶのは最初の例です。たとえば、多くの変数に応じて特定のページを表示したいという、ちょっと変わったロジックにたまたまいるとします。

英語:「ログインしているユーザーが管理者の教師ではなく、通常の教師であり、学生自身ではない場合...」

if not user.isAdmin() and user.isTeacher() and not user.isStudent():
    doSomething()

確かにこれは問題なく見えるかもしれませんが、ifステートメントを読むのは大変な作業です。意味のあるラベルにロジックを割り当ててみませんか。「ラベル」は実際には変数名です。

displayTeacherPanel = not user.isAdmin() and user.isTeacher() and not user.isStudent()
if displayTeacherPanel:
    showTeacherPanel()

これはばかげているように見えるかもしれませんが、教師パネルを表示している場合、またはデフォルトでユーザーが他の特定のパネルにアクセスできる場合にのみ、別の項目を表示したいという別の条件がある可能性があります。

if displayTeacherPanel or user.canSeeSpecialPanel():
    showSpecialPanel()

変数を使用せずに上記の条件を記述して、ロジックを格納およびラベル付けします。非常に面倒で読みにくい論理ステートメントになってしまうだけでなく、自分自身を繰り返しただけです。妥当な例外はありますが、次の点に注意してください。自分を繰り返さないでください(DRY)。


3

「all」と「any」は、同じタイプのケースの多くの条件に適しています。ただし、常にすべての条件を評価します。この例に示すように:

def c1():
    print " Executed c1"
    return False
def c2():
    print " Executed c2"
    return False


print "simple and (aborts early!)"
if c1() and c2():
    pass

print

print "all (executes all :( )"
if all((c1(),c2())):
    pass

print

5
不正解です。彼らがするのはあなたがするからです。[c1、c2]のfに対してall(f()を試してください)。
habnabit 2009年

2
彼は関数を簡単に印刷させることができるので、例としてのみ関数を使用していたと思います。それまでにリストで提供された一連の任意の式を検討している場合all()、それらをそれぞれラムダでラップしてf()トリックを使用しない限り、それらはすべて評価されます。言い換えれば、アーロン:アンダースは、呼び出し可能オブジェクトを具体例として使用して、一般的な条件について話していたと思います。ただし、リジョイナーは関数にのみ適用されます。
Brandon Rhodes

3

(固定幅の名前は実際のコード(少なくとも私が遭遇する実際のコードではない)を表すものではなく、例の読みやすさを信じないため、識別子を軽く変更しました。)

if (cond1 == "val1" and cond22 == "val2"
and cond333 == "val3" and cond4444 == "val4"):
    do_something

これは「and」と「or」(2行目の最初にあることが重要です)に対してはうまく機能しますが、他の長い条件に対してはそれほど効果的ではありません。幸いなことに、前者の方が一般的なケースのようですが、後者は一時変数で簡単に書き直すことができます。(通常は難しいことではありませんが、「and」/「or」の短絡を保持して書き換えるのは難しい場合や、わかりにくい場合があります。)

C ++に関するブログ投稿からこの質問を見つけたので、私のC ++スタイルが同じであることを含めます。

if (cond1 == "val1" and cond22 == "val2"
and cond333 == "val3" and cond4444 == "val4") {
    do_something
}

3

単純明快で、pep8チェックもパスします。

if (
    cond1 and
    cond2
):
    print("Hello World!")

AndとOrの比較をめったに混ぜないので、私はalland any関数を好むようになりました。

if all([
    cond1,
    cond2,
]):
    print("Hello World!")

ただ1つのイテラブルを渡すことを忘れないでください!N引数の受け渡しは正しくありません。

注:anyは多くのor比較のようでallあり、多くのand比較のようです。


これは、ジェネレータの内包表現とうまく結合します。次に例を示します。

# Check if every string in a list contains a substring:
my_list = [
    'a substring is like a string', 
    'another substring'
]

if all('substring' in item for item in my_list):
   print("Hello World!")

# or

if all(
    'substring' in item
    for item in my_list
):
    print("Hello World!")

さらに詳しく:ジェネレーターの理解


1
また、pylintのストック構成では、ifの行の継続にインデントが必要であることも指摘しておきます。これは私がこのスキームを使用することを思いとどまらせました。
ThorSummoner 16

2

条件と本文の間に追加の空白行を挿入し、残りを標準的な方法で実行するとどうなりますか?

if (cond1 == 'val1' and cond2 == 'val2' and
    cond3 == 'val3' and cond4 == 'val4'):

    do_something

psスペースではなく常にタブを使用します。微調整できません...


3
これは、特に条件式の本文が長い場合、非常に混乱するでしょう。
Eli Bendersky、2008年

私はエリに同意します。ここでのカプセル化とインデントは長い行を混乱させるものです。さらに、新しいルールでは、andand orステートメントは次の行から開始する必要があります
virtualxtc

2

私が通常行うことは次のとおりです。

if (cond1 == 'val1' and cond2 == 'val2' and
    cond3 == 'val3' and cond4 == 'val4'
   ):
    do_something

このように、閉じ中括弧とコロンは視覚的に私たちの状態の終わりを示します。


1
ほぼ正しい。PEP 8は、andまたはの前で中断することを推奨していorます。
virtualxtc 2018

2

ifステートメントに複数の条件を提供するすべての回答者は、問題が提示したのと同じくらい醜いです。同じことを実行しても、この問題は解決されません。

PEP 0008の回答でさえ、反発的です。

これははるかに読みやすいアプローチです

condition = random.randint(0, 100) # to demonstrate
anti_conditions = [42, 67, 12]
if condition not in anti_conditions:
    pass

私の言葉を食べて欲しいですか?マルチコンディショナルが必要だと私に納得させてください。文字通りこれを印刷して、娯楽のために食べます。


これは確かに複数条件を実行する非常にきちんとした方法です:)なぜそれがより多くの票を持たないのか分かりません:)、注意点はありますか?
dim_user 2018年

@SaulCruzは本当にありません。条件変数を繰り返す必要がないだけでなく、各値をチェックする多くの重複を節約します。これにより、値のみを配列に入れ、エンジンに(最適化された)ジョブを実行させます。あなたのために状態をチェックします
Stoff

@Stoffコメントを削除していただきありがとうございます。私はあなたのアプローチがOPの質問に答えないことを指摘したかったのです。あなたが提供するコードは、問題のコードに適用できません。そうでない場合は、アプローチによって再フォーマットされたOPのコードを追加して、ポイントを証明する必要があります。
ジェイコモン

それは受け入れられた答えではありませんが、それは明らかに別のアプローチです(他の人は同意します)。だから、別の答えを奨励したので、引数は正確には何ですか?自分の質問を明確にします。適切な注意が必要な場合は、おそらく自分の質問を開くことを検討してください。PS私はSO modではありません。コメントを削除できません
Stoff

2

@zkandaの解決策は少し工夫すれば良いと思います。条件と値がそれぞれのリストにある場合は、リスト内包表記を使用して比較を行うことができます。これにより、条件と値のペアを追加するのが少し一般的になります。

conditions = [1, 2, 3, 4]
values = [1, 2, 3, 4]
if all([c==v for c, v in zip(conditions, values)]):
    # do something

このようなステートメントをハードコーディングしたい場合は、読みやすくするために次のように記述します。

if (condition1==value1) and (condition2==value2) and \
   (condition3==value3) and (condition4==value4):

そして、iand演算子で別のソリューションをそこに捨てるだけです:

proceed = True
for c, v in zip(conditions, values):
    proceed &= c==v

if proceed:
    # do something

1
ちょうど楽しみのために:all(map(eq, have, expected))。(ありfrom operator import eq
ガブリエルガルシア

1

完全を期すために、その他のランダムなアイデアをいくつかご紹介します。彼らがあなたのために働くなら、それらを使ってください。それ以外の場合は、おそらく何か他のものを試す方が良いでしょう。

辞書でこれを行うこともできます:

>>> x = {'cond1' : 'val1', 'cond2' : 'val2'}
>>> y = {'cond1' : 'val1', 'cond2' : 'val2'}
>>> x == y
True

このオプションはより複雑ですが、便利な場合もあります。

class Klass(object):
    def __init__(self, some_vars):
        #initialize conditions here
    def __nonzero__(self):
        return (self.cond1 == 'val1' and self.cond2 == 'val2' and
                self.cond3 == 'val3' and self.cond4 == 'val4')

foo = Klass()
if foo:
    print "foo is true!"
else:
    print "foo is false!"

それがあなたのために働くならDunno、しかしそれは考慮すべきもう一つのオプションです。ここにもう一つの方法があります:

class Klass(object):
    def __init__(self):
        #initialize conditions here
    def __eq__(self):
        return (self.cond1 == 'val1' and self.cond2 == 'val2' and
               self.cond3 == 'val3' and self.cond4 == 'val4')

x = Klass(some_values)
y = Klass(some_other_values)
if x == y:
    print 'x == y'
else:
    print 'x!=y'

最後の2つはテストしていませんが、それがあなたがやりたいことであるなら、コンセプトはあなたを動かすのに十分でなければなりません。

(そして、記録のために、これが1回限りのものである場合、おそらく最初に提示した方法を使用する方がよいでしょう。多くの場所で比較を行っている場合、これらの方法は、それらが一種のハックであるという事実についてそれほど悪くは感じません。)


1

私もこれを行うための適切な方法を見つけるのに苦労していたので、アイデアを思いつきました(これは主に好みの問題なので、特効薬ではありません)。

if bool(condition1 and
        condition2 and
        ...
        conditionN):
    foo()
    bar()

私が見た他のソリューションと比較して、このソリューションにはいくつかのメリットがあります。つまり、インデント(ブール)の余分な4スペースが得られ、すべての条件を垂直に並べることができ、ifステートメントの本文をインデントできます。明確な(方法)方法。これはブール演算子の短絡評価の利点も維持しますが、基本的に何もしない関数呼び出しのオーバーヘッドを追加します。引数を返す任意の関数をboolの代わりにここで使用できると(妥当に)主張できますが、私が言ったように、それは単なるアイデアであり、最終的には好みの問題です。

おかしなことに、私がこれを書いていて「問題」について考えていたとき、私は関数呼び出しのオーバーヘッドを取り除くさらに別のアイデアを思いつきました。括弧のペアを追加して、複雑な条件を入力しようとしていることを示してみませんか?さらに2つ言って、ifステートメントの本文に関連するサブ条件の2スペースのインデントを作成します。例:

if (((foo and
      bar and
      frob and
      ninja_bear))):
    do_stuff()

あなたがそれを見ると、すぐに「ちょっと、ここで複雑なことが起こっている!」。はい、かっこは読みやすさを向上させないことはわかっていますが、これらの条件が表示されることはめったにないはずです。表示される場合は、とにかく停止して注意深く読む必要があります(それらは複雑であるため)。

とにかく、私がここで見たことのないもう2つの提案だけです。これが誰かを助けることを願っています:)


1

あなたはそれを2行に分割することができます

total = cond1 == 'val' and cond2 == 'val2' and cond3 == 'val3' and cond4 == val4
if total:
    do_something()

または、一度に1つの条件を追加することもできます。このようにして、少なくともクラッタをから分離しifます。


1

私はこのスレッドが古いことを知っていますが、Python 2.7コードがいくつかあり、PyCharm(4.5)はまだこのケースについて不満を言っています。

if foo is not None:
    if (cond1 == 'val1' and cond2 == 'val2' and
        cond3 == 'val3' and cond4 == 'val4'):
            # some comment about do_something
            do_something

PEP8の警告「視覚的にインデントされた行が次の論理行と同じインデント」であっても、実際のコードは完全に問題ありませんか?「インデントしすぎ」ではありませんか?

... Pythonが弾丸に噛み付き、中括弧で終わってほしかったときがあります。偶然のインデントの誤りにより、何年にもわたって多くのバグが誤って導入されたのでしょうか...


0

条件をリストにまとめ、smthを実行します。お気に入り:

if False not in Conditions:
    do_something

0

長い条件がある場合、コード本体が短いことがよくあります。その場合は、本文をダブルインデントするだけなので、次のようになります。

if (cond1 == 'val1' and cond2 == 'val2' and
    cond3 == 'val3' and cond4 == 'val4'):
        do_something

1
@qarma、拡張してもらえますか?これは、PEP 8で推奨されていない行継続文字を使用するよりも確実に優れています
xorsyst

これは実際には行継続の有効なケースです。IMPO括弧は、タプルまたは関数呼び出しを示します。OPの使用は非常にCに似ています。可能な限り、Python構文を使用します。\は普遍的に支持されているわけではないことを認めます。
Dima Tisnek

0
  if cond1 == 'val1' and \
     cond2 == 'val2' and \
     cond3 == 'val3' and \
     cond4 == 'val4':
      do_something

またはこれがより明確な場合:

  if cond1 == 'val1'\
     and cond2 == 'val2'\
     and cond3 == 'val3'\
     and cond4 == 'val4':
      do_something

この場合、インデントが4の倍数であるべき理由はありません。たとえば、「開始区切り文字と整列」を参照してください。

http://google-styleguide.googlecode.com/svn/trunk/pyguide.html?showone=Indentation#Indentation


Googleのガイドには、OPで言及されている「これを行う最も明白な方法」と一致する複雑な条件の例も記載されています。ガイドは、長い "if"をそのようにフォーマットすることを明示的に推奨していませんが。
アントンストロゴノフ2012

0

ここに別のアプローチがあります:

cond_list = ['cond1 == "val1"','cond2=="val2"','cond3=="val3"','cond4=="val4"']
if all([eval(i) for i in cond_list]):
 do something

これにより、リストに別の条件を追加するだけで、ifステートメントを変更せずに別の条件を簡単に追加することもできます。

cond_list.append('cond5=="val5"')


0

if&else条件がその中で複数のステートメントを実行する必要がある場合、以下のように書くことができます。内部に1つのステートメントがある場合の例です。

ありがとうございます。

#!/usr/bin/python
import sys
numberOfArgument =len(sys.argv)
weblogic_username =''
weblogic_password = ''
weblogic_admin_server_host =''
weblogic_admin_server_port =''


if numberOfArgument == 5:
        weblogic_username = sys.argv[1]
        weblogic_password = sys.argv[2]
        weblogic_admin_server_host =sys.argv[3]
        weblogic_admin_server_port=sys.argv[4]
elif numberOfArgument <5:
        print " weblogic UserName, weblogic Password and weblogic host details are Mandatory like, defalutUser, passwordForDefaultUser, t3s://server.domainname:7001 ."
        weblogic_username = raw_input("Enter Weblogic user Name")
        weblogic_password = raw_input('Enter Weblogic user Password')
        weblogic_admin_server_host = raw_input('Enter Weblogic admin host ')
        weblogic_admin_server_port = raw_input('Enter Weblogic admin port')
#enfelif
#endIf

0

私の初心者を許してください、しかし私はここの誰よりも#Pythonの知識があまりないことがありますが、3D BIMモデリングで自分のオブジェクトをスクリプト化するときに同じようなものを見つけたので、アルゴリズムをPythonのもの。

私がここで見つける問題は両面です:

  1. スクリプトを解読しようとする人にとって、私は外国人のように思えます。
  2. これらの値が変更された場合(最も可能性が高い)、または新しい条件を追加する必要がある場合(破損したスキーマ)、コードのメンテナンスは高コストになります。

これらすべての問題を回避するには、スクリプトを次のようにする必要があります

param_Val01 = Value 01   #give a meaningful name for param_Val(i) preferable an integer
param_Val02 = Value 02
param_Val03 = Value 03
param_Val04 = Value 04   # and ... etc

conditions = 0           # this is a value placeholder

########
Add script that if true will make:

conditions = conditions + param_Val01   #value of placeholder is updated
########

### repeat as needed


if conditions = param_Val01 + param_Val02 + param_Val03 + param_Val04:
    do something

この方法の長所:

  1. スクリプトは読み取り可能です。

  2. スクリプトは簡単に保守できます。

  3. 条件は、目的の条件を表す値の合計に対する1つの比較演算です。
  4. マルチレベルの条件は不要

それがあなたを助けることを願っています

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.