時々私はif
sの長い条件を数行に分けます。これを行う最も明白な方法は次のとおりです。
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番目の条件付き行に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年以降)これは角かっこの使用を推奨しています。
単純なANDまたはORの縮退の場合は、次のようにしました。
if all( [cond1 == 'val1', cond2 == 'val2', cond3 == 'val3', cond4 == 'val4'] ):
if any( [cond1 == 'val1', cond2 == 'val2', cond3 == 'val3', cond4 == 'val4'] ):
それは数文字を削り、その状態に微妙なものがないことを明確にしています。
誰か ここで垂直空白の使用を支持しなければならない! :)
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の価値があります。
これは私の個人的な見方です。長い条件は(私の考えでは)ブール値を返す関数/メソッドへのリファクタリングを示唆するコードの匂いです。例えば:
def is_action__required(...):
return (cond1 == 'val1' and cond2 == 'val2'
and cond3 == 'val3' and cond4 == 'val4')
さて、複数行の条件を見栄えよくする方法が見つかった場合は、おそらくそれらを使用して満足していることに気付き、リファクタリングをスキップします。
その一方で、彼らに私の審美的な感覚を混乱させることはリファクタリングの動機として働きます。
したがって、私の結論は、複数の回線条件が見苦しいように見えるはずであり、これはそれらを避けるための動機となります。
これはそれほど改善されませんが...
allCondsAreOK = (cond1 == 'val1' and cond2 == 'val2' and
cond3 == 'val3' and cond4 == 'val4')
if allCondsAreOK:
do_something
私はひどく大きいif条件があるとき私はこのスタイルを好みます:
if (
expr1
and (expr2 or expr3)
and hasattr(thingy1, '__eq__')
or status=="HappyTimes"
):
do_stuff()
else:
do_other_stuff()
and
キーワードを2行目に移動し、条件を含むすべての行を4つではなく2つのスペースでインデントすることをお勧めします。
if (cond1 == 'val1' and cond2 == 'val2'
and cond3 == 'val3' and cond4 == 'val4'):
do_something
これがまさに私のコードでこの問題を解決する方法です。行の最初の単語としてキーワードを使用すると、条件が読みやすくなります。スペースの数を減らすと、条件とアクションがさらに区別されます。
PEP 0008 (Pythonの公式スタイルガイド)それはこの問題についてささやかな長さでコメントしているので引用する価値があるようです:
if
ステートメントの条件部分が複数行にまたがることを要求するのに十分な長さであるとき、2文字のキーワード(すなわちif
)と単一のスペース、そして開き括弧の組み合わせが自然なものになることは注目に値します複数行の条件式の後続行を4スペースでインデントします。これは、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()
上記の引用文の「に限定されない」に注意してください。スタイルガイドで提案されているアプローチのほかに、この質問に対する他の回答で提案されているアプローチのいくつかも受け入れられます。
これが私がしていることです、 "all"と "any"がイテラブルを受け入れることを忘れないでください、それで私はただ長い条件をリストに入れて、そして "all"に仕事をさせます。
condition = [cond1 == 'val1', cond2 == 'val2', cond3 == 'val3', cond4 == 'val4']
if all(condition):
do_something
個人的には、長い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()
これはばかげているように思えるかもしれませんが、他の特定のパネルへのアクセス権がある場合にのみ教師パネルORを表示している場合に限り、別の項目を表示したいという別の条件があります。デフォルトでは
if displayTeacherPanel or user.canSeeSpecialPanel():
showSpecialPanel()
ロジックを保存してラベルを付けるために変数を使用せずに上記の条件を書いてみてください。そして、非常に面倒で読みにくい論理ステートメントになってしまうだけでなく、繰り返しています。合理的な例外がありますが、覚えておいてください。
私は自分の好みの解決策を見ていないことに驚きました、
if (cond1 == 'val1' and cond2 == 'val2'
and cond3 == 'val3' and cond4 == 'val4'):
do_something
and
はキーワードなので、私のエディタで強調表示され、その下のdo_somethingとはかなり異なって見えます。
@krawyotiが言ったことに加えて...長い条件は読みにくく理解しにくいので匂いがします。関数または変数を使用すると、コードが明確になります。 Pythonでは、式が "浮動"のように見えないように、縦方向のスペースを使用し、括弧を囲み、各行の先頭に論理演算子を配置することを好みます。
conditions_met = (
cond1 == 'val1'
and cond2 == 'val2'
and cond3 == 'val3'
and cond4 == 'val4'
)
if conditions_met:
do_something
while
ループのように、条件を複数回評価する必要がある場合は、ローカル関数を使用するのが最善です。
「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
(固定幅の名前は実際のコードを表しているのではなく、少なくとも私が遭遇する実際のコードではないので、私は識別子をわずかに変更しました。そして例の読みやすさを信じます。)
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
}
平易で単純な、またpep8チェックを渡します:
if (
cond1 and
cond2
):
print("Hello World!")
AndとOrの比較をうまく組み合わせることはめったにないので、最近ではall
関数とany
関数を好んで使用しています。また、Failing Earlyというジェネレーターの理解という利点もあります。
if all([
cond1,
cond2,
]):
print("Hello World!")
ただ一つのイテラブルを渡すことを忘れないでください! 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!")
条件と本体の間に追加の空白行を挿入し、残りを正規の方法で挿入しただけではどうなりますか
if (cond1 == 'val1' and cond2 == 'val2' and
cond3 == 'val3' and cond4 == 'val4'):
do_something
pS私はいつもスペースではなくタブを使います。微調整できません….
私が普段していることは、
if (cond1 == 'val1' and cond2 == 'val2' and
cond3 == 'val3' and cond4 == 'val4'
):
do_something
このように、閉じ括弧とコロンは視覚的に私たちの状態の終わりを示します。
私もこれを行うためのまともな方法を見つけるのに苦労していたので、私はアイデアを思いついた(これは主に好みの問題なので、銀の弾丸ではない)。
if bool(condition1 and
condition2 and
...
conditionN):
foo()
bar()
私が見た他のものと比較して、このソリューションにはいくつかのメリットがあります。つまり、すべての条件を垂直に並べることができる4つのインデントスペース(bool)が追加されます。明快な方法です。これはブール演算子の短絡評価の利点も保持しますが、もちろん基本的には何もしない関数呼び出しのオーバーヘッドを追加します。あなたはその引数を返すどんな関数でもboolの代わりにここで使うことができると主張することができますが、私が言ったようにそれは単なるアイデアであり、そしてそれは最終的に好みの問題です。
私がこれを書いていて「問題」について考えていたとき、私は さらに別の という考えを思いついたので、関数呼び出しのオーバーヘッドを取り除きました。余計な括弧を使って複雑な条件に入ることを示してはどうでしょうか。さらに2つ言うと、ifステートメントの本体に対する副条件のニース2スペースのインデントを指定します。例:
if (((foo and
bar and
frob and
ninja_bear))):
do_stuff()
あなたがそれを見たとき、すぐに と言ってあなたの頭の中でベルが鳴るので、私はこういうのが好きです。「ねえ、ここで起こっている複雑なことがあります!」 。はい、括弧は読みやすさには役立たないことを知っていますが、これらの条件はめったに表示されないはずであり、表示されたら、とにかく慎重に停止して読む必要があります(complex) 。
とにかく、ここでは見たことがないもう2つの提案があります。これが誰かに役立つことを願っています:)
完全を期すために、他にいくつかランダムに考えてみましょう。それらがあなたのために働くならば、それらを使ってください。それ以外の場合は、おそらく他の何かを試した方がいいでしょう。
辞書を使ってこれを行うこともできます。
>>> 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それがあなたのために働くならば、それは考慮するべきもう一つの選択肢です。もう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つはテストしていませんが、それでも構いたいのであれば概念は十分に理解できるはずです。
(そして、記録として、これが一度だけの場合は、最初に提示した方法を使用するほうがおそらく賢明です。多くの場所で比較を行っている場合は、これらの方法によって読みやすさが向上します。あなたは彼らが一種のハッキーであるという事実についてそれほど気分が悪くないと思う。)
あなたはそれを2行に分割することができます
total = cond1 == 'val' and cond2 == 'val2' and cond3 == 'val3' and cond4 == val4
if total:
do_something()
あるいは、一度に1つの条件を追加することもできます。そのように、少なくともそれはif
からクラッタを分離します。
私はこのスレッドが古いことを知っています、しかし私はいくつかの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が弾丸を噛んで中括弧だけで終わったほうがいいと思うことがあります。偶然の誤った字下げのせいで、何年間に何個のバグが偶然にもたらされたのだろうか。
Ifステートメントに複数の条件を付けたすべての回答者は、提示された問題と同じくらい醜いです。同じことをしてもこの問題は解決できません。
PEP 0008の答えでさえ反発的です。
これははるかに読みやすいアプローチです。
condition = random.randint(0, 100) # to demonstrate
anti_conditions = [42, 67, 12]
if condition not in anti_conditions:
pass
私の言葉を食べてもらいたいですか?私はあなたが複数の条件を必要とし、私は文字通りこれを印刷してあなたの娯楽のためにそれを食べるつもりだと納得させなさい。
私は@ 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
以下のように書くことができるよりも、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
私は長い条件があるとき、私はしばしば短いコード本体を持っていることに気付きます。その場合は、本体を二重インデントするだけです。
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()
あなたの条件をリストにまとめて、そしてsmthをしなさい。好きです:
if False not in Conditions:
do_something
これは別のアプローチです:
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"')
このようなものが最も読みやすいオプションだと思います。
for pet in Zoo:
cute = every_pet()
furry = hair is 'over9000'
small = size < min_size
if cute and furry and small:
return 'I need to feed it!'
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