795

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

  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

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

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

4

30 に答える 30

893

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

これがStyle Guideで、(2010 年以降) ブラケットの使用が推奨されています。

于 2008-10-08T06:34:25.267 に答える
140

単に AND または OR である退化したケースでは、次のように頼りました。

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

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

いくつかの文字を削り、状態に微妙な点がないことを明確にしています。

于 2008-10-08T10:26:48.247 に答える
63

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

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

はい、明確にするために、垂直方向の不動産を少しトレードオフしています。それだけの価値があります。

于 2008-10-08T14:55:02.933 に答える
50

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

if (
    expr1
    and (expr2 or expr3)
    and hasattr(thingy1, '__eq__')
    or status=="HappyTimes"
):
    do_stuff()
else:
    do_other_stuff()
于 2008-10-08T08:39:58.620 に答える
28

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

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

さて、複数行の条件の見栄えを良くする方法を見つけたら、おそらくそれで満足し、リファクタリングをスキップするでしょう。

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

したがって、私の結論は、複数行の条件は見苦しく見えるはずであり、これはそれらを避けるインセンティブになるということです。

于 2011-01-14T10:50:32.403 に答える
26

なかなか改善されませんが…

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

if allCondsAreOK:
   do_something
于 2008-10-08T06:31:54.790 に答える
19

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

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

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

于 2008-10-08T07:19:09.780 に答える
16

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

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

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

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

于 2015-07-05T14:15:27.350 に答える
5

個人的には、長い 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)。

于 2013-03-07T06:24:12.010 に答える
5

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

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

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

于 2011-01-19T20:53:39.250 に答える
4

自分の好みの解決策が見つからないことに驚いています。

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

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

于 2011-01-14T14:50:50.417 に答える
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
}
于 2011-01-14T08:33:47.987 に答える
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
于 2008-10-08T10:38:37.490 に答える
2

条件と本体の間に追加の空白行を挿入するだけで、残りは正規の方法で行うとどうなるでしょうか?

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

    do_something

ps スペースではなく、常にタブを使用します。微調整が出来ない…

于 2008-10-09T02:45:40.300 に答える
1

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

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

または、一度に 1 つの条件を追加することもできます。そうすれば、少なくとも雑然としたものをif.

于 2016-08-04T19:30:45.363 に答える
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!"

それがうまくいくかどうかはわかりませんが、考慮すべき別のオプションです。もう1つの方法は次のとおりです。

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 回限りのことである場合は、最初に提示した方法を使用した方がよいでしょう。多くの場所で比較を行っている場合、これらの方法により読みやすさが向上し、彼らが一種のハッキーであるという事実についてそれほど気分が悪いわけではありません。)

于 2008-10-08T17:26:00.320 に答える
0

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

if (cond1 == 'val1' and cond2 == 'val2' and
    cond3 == 'val3' and cond4 == 'val4'):
        do_something
于 2011-09-22T08:31:27.493 に答える
0

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

おかげでうまくいきました。

#!/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
于 2015-12-06T12:27:55.893 に答える
0

条件をリストにパックしてから、smth を実行します。お気に入り:

if False not in Conditions:
    do_something
于 2010-06-09T09:23:43.607 に答える
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=インデント#インデント

于 2012-03-13T11:13:19.927 に答える
0

私は通常使用します:

if ((cond1 == 'val1' and cond2 == 'val2' and
     cond3 == 'val3' and cond4 == 'val4')):
    do_something()
于 2015-03-05T00:12:32.823 に答える
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"')
于 2014-10-16T22:08:03.513 に答える