Pythonで次のようなものを書くと
foo==bar and spam or eggs
ブール文が true の場合、python はスパムを返し、それ以外の場合は卵を返すように見えます。誰かがこの動作を説明できますか? 式が長いブール値のように評価されないのはなぜですか?
編集:具体的には、式の結果として「スパム」または「卵」が返されるメカニズムを理解しようとしています。
Pythonで次のようなものを書くと
foo==bar and spam or eggs
ブール文が true の場合、python はスパムを返し、それ以外の場合は卵を返すように見えます。誰かがこの動作を説明できますか? 式が長いブール値のように評価されないのはなぜですか?
編集:具体的には、式の結果として「スパム」または「卵」が返されるメカニズムを理解しようとしています。
演算子and
とor
はショートサーキットです。つまり、式の結果が最初のオペランドのみの評価から推測できる場合、2 番目のオペランドは評価されません。たとえば、式があり、truea or b
とa
評価された場合、それが何であるかは関係ありません。b
式の結果は true であるため、b
評価されません。それらは実際には次のように機能します。
a and b
: a が false の場合、b は評価されずに a が返されます。それ以外の場合は b が返されます。a or b
: a が true の場合、b は評価されずに a が返されます。そうでない場合は b が返されます。Falsey と Truthy は、ブール値のコンテキストで false または true に評価される値を参照します。
ただし、このおよび/または慣用句は、より良い代替手段がなかった時代に役立ちましたが、現在はより良い方法があります:
spam if foo==bar else eggs
and/or イディオムの問題点は (初心者にとって混乱を招くことは別として)、条件が true であるにもかかわらず、spam が誤った値 (空の文字列など) に評価された場合に間違った結果が返されることです。このため、それを避ける必要があります。
これは、Python のブール演算子がどのように機能するかです。
ドキュメントから(最後の段落では、オペレーターがそのように動作することが良い考えである理由を説明しています):
ブール演算のコンテキストで、また制御フロー ステートメントで式が使用される場合、次の値は false として解釈されます:
False
、None
、すべての型の数値ゼロ、および空の文字列とコンテナー (文字列、タプル、リスト、辞書、セットを含む)およびフリーズセット)。他のすべての値は true として解釈されます。(__nonzero__()
これを変更する方法については、特別な方法を参照してください。)演算子は、引数が false の場合に
not
生成され、そうでない場合に生成されます。True
False
式
x and y
は最初に評価されx
ます。が false の場合x
、その値が返されます。それ以外の場合y
は評価され、結果の値が返されます。式
x or y
は最初に評価されx
ます。が true の場合x
、その値が返されます。それ以外の場合、y が評価され、結果の値が返されます。(これらがおよびに返す値と型を制限し
and
たり制限したりするのではなく、最後に評価された引数を返すことに注意してください。これは便利な場合があります。いずれにせよ値を発明しなければならないので、わざわざその引数と同じ型の値を返すことはないので、例えばyieldsではなく.)or
False
True
s
s or 'foo'
not
not 'foo'
False
''
その理由は、Python が関係する変数の実際の値を使用してブール式を評価し、それらを値に制限するのではなく、評価するためTrue
ですFalse
。次の値は false と見なされます。
None
False
''
, ()
, []
, {}
)__nonzero__()
0 を返すまたは__len__()
メソッドを使用したユーザー定義型False
詳細については、Python ドキュメンテーションの真理値テストのセクションを参照してください。特に:
ブール値の結果を持つ演算および組み込み関数は、特に明記されていない限り、常にfalse および
0
orを返します。(重要な例外: ブール演算とは常にオペランドの 1 つを返します。)False
1
True
or
and
括弧を使用して、式があいまいにならないようにしてください。そのままでは、次のようになります。
(foo == bar and spam) or eggs