はじめに
今回はPythonのif文の動きについて少し掘り下げてみよう。
以下のコードはTrue
とFalse
どちらを出力するだろうか。
1 | if 0: |
また、以下のコードだとどうだろうか。
1 | if 1: |
上記の例はプログラミングに慣れた人だと知っているかもしれない。
では、
1 | if 2: |
1 | if ['A']: |
1 | if []: |
1 | if 'apple': |
だとどうなるだろうか。エラーは発生するだろうか。
結論から言うと、エラーは発生しない。
何らかの形で、オブジェクトは真理値として判定できるからだ。
真理値判定
どのようなオブジェクトでも真理値として判定でき、ifやwhileの条件あるいは以下のブール演算の被演算子として使えます。オブジェクトは、デフォルトでは真と判定されます。ただしそのクラスが __bool__()メソッドを定義していて、それがFalseを返す場合、または__len__()メソッドを定義していて、それが0を返す場合は偽と判定されます。
(https://docs.python.org/ja/3/library/stdtypes.html#truth)
つまり、はじめに
で示した例だと、
1 | >>> bool(0) |
が、__bool__()
の値であり、かつ問題の答え(標準出力される文字列)となる。
(数値型のbool()
は0のみがFalse
となる)
ここでふと疑問が浮かぶ。
__bool__()
と__len__()
はどちらが優先度が高いのだろう。
クラスを作って、実験してみよう。
__bool__()
と__len__()
__bool__()
がTrue、__len__()
が0の場合
だとどうなるのだろうか。
1 | class MyClass: |
__bool__()
が優先されている。
1 | True |
__bool__()
がFalse、__len__()
が非0の場合
1 | class MyClass: |
1 | False |
こちらも__bool__()
が優先されている。
つまり、__bool__()
の優先順位が高いと言える。
実は、答えはドキュメントからも読み取れる。
object.bool(self)真理値テストや組み込み演算bool()を実装するために呼び出されます。このメソッドが定義されていないとき、__len__()が定義されていれば呼び出され、その結果が非0であれば真とみなされます。
(https://docs.python.org/ja/3/reference/datamodel.html#object.__bool__)
__bool__()
も__len__()
も定義されていない場合
ドキュメントにあったように、オブジェクトはデフォルトではTrue
となる。
1 | class MyClass: |
1 | True |
まとめ
__bool__()
を評価する。__bool__()
が定義されていない場合、__len__()
を評価する。__len__()
が定義されていない場合、True
を返却する。
記事情報
- 投稿日:2020年3月15日
- 最終更新日:2020年3月15日