Rubyist が Python のコードを書くと、はまりそうな所(不定期)
sample1.xml
<?xml version="1.0" encoding="utf-8"?> <elem1> <elem2_1> <elem3/> </elem2_1> <elem2_2/> </elem1>
sample1.py
import xml.etree.ElementTree as ET def is_true_or_false(it): if it: print('True') else: print('False') et = ET.parse('sample1.xml') elem1 = et.getroot() elem2_1 = elem1.find('elem2_1') elem2_2 = elem1.find('elem2_2') print('%s is ' % (elem2_1.tag,), end='') is_true_or_false(elem2_1) print('%s is ' % (elem2_2.tag,), end='') is_true_or_false(elem2_2) print('%s.__len__() is %s' % (elem2_1.tag, elem2_1.__len__())) print('%s.__len__() is %s' % (elem2_2.tag, elem2_2.__len__()))
実行結果
$ python3.1 sample1.py elem2_1 is True elem2_2 is False elem2_1.__len__() is 1 elem2_2.__len__() is 0
Python のライブラリリファレンスマニュアルの「4.1. 真理値判定」( http://docs.python.jp/3/library/stdtypes.html#truth-value-testing )を見ると、
どのオブジェクトも真理値を判定でき、if や while 条件に、または以下のブール演算の被演算子に使えます。以下の値は偽と見なされます:
- None
- False
- 数値型におけるゼロ。例えば 0, 0.0, 0j。
- 空のシーケンス。例えば '', (), []。
- 空のマッピング。例えば {}。
- ユーザ定義クラスのインスタンスで、そのクラスが __bool__() または __len__() メソッドを定義していれば、それらのメソッドが整数 0 または bool 値 False を返すとき。[1]
それ以外の全ての値は真と見なされます — 従って、多くの型のオブジェクトは常に真です。
ブール値の結果を返す演算および組み込み関数は、特に注釈のない限り常に偽値として 0 または False を返し、真値として 1 または True を返します (重要な例外: ブール演算 or および and は常に被演算子のうちの一つを返します)。
脚注[1] これらの特殊なメソッドのさらなる情報は、Python リファレンスマニュアル (基本的なカスタマイズ( http://docs.python.jp/3/reference/datamodel.html#basic-customization )) を参照下さい。( ←「object.__bool__(self)」の所)
ゼロや空のコレクションは普通に注意していれば大丈夫だと思いますが、最後の規則で、例に挙げたような __bool__() メソッドが無く、普通のオブジェクトだが便利さのためにコレクション風のメソッド群を実装していて、obj.__len__() が 0 を返すので偽になるのは、うっかりするとうっかりする危険が高いように思いますので、特に注意が必要と思われます。